From fd4e87a0d1d8efa0f3a924a5e5cdd47f10b336dc Mon Sep 17 00:00:00 2001 From: Jeffery Miller Date: Thu, 20 Apr 2023 11:35:59 -0500 Subject: [PATCH] Input: synaptics-rmi4 - retry reading SMBus version on resume When resuming from suspend there is a delay where getting the version data from the smbus returns -ENXIO. This causes the rmi4 resume to fail and the touchpad to stop working after resume. In lieu of finding what this really needs to wait on just retry a few times so it works. The limit of 100ms is arbitrary. My tests have shown this to take an extra 7-12ms on resume to succeed on the Lenovo t440p machine. Logs on resume now look something like: ``` [ 108.622951] rmi4_smbus 0-002c: calling rmi_smb_resume+0x0/0x63 [rmi_smbus] @ 3975, parent: i2c-0 ... [ 108.623132] rmi4_smbus 0-002c: failed to get SMBus version number! [ 108.623134] rmi4_smbus 0-002c: sleeping to try again [ 108.626003] rmi4_smbus 0-002c: failed to get SMBus version number! [ 108.626005] rmi4_smbus 0-002c: sleeping to try again [ 108.629025] rmi4_smbus 0-002c: failed to get SMBus version number! [ 108.629028] rmi4_smbus 0-002c: sleeping to try again [ 108.632017] rmi4_smbus 0-002c: failed to get SMBus version number! [ 108.632019] rmi4_smbus 0-002c: sleeping to try again [ 108.636172] rmi4_smbus 0-002c: wrote 4 bytes at 0x86: 0 (4c 00 01 00) ``` Signed-off-by: Jeffery Miller --- drivers/input/rmi4/rmi_smbus.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/input/rmi4/rmi_smbus.c b/drivers/input/rmi4/rmi_smbus.c index 4bf0e1df6a4a..1fccad5811cf 100644 --- a/drivers/input/rmi4/rmi_smbus.c +++ b/drivers/input/rmi4/rmi_smbus.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -44,14 +45,27 @@ static int rmi_smb_get_version(struct rmi_smb_xport *rmi_smb) struct i2c_client *client = rmi_smb->client; int retval; + unsigned long deadline = jiffies + msecs_to_jiffies(100); + unsigned long before = jiffies; + /* Check if for SMBus new version device by reading version byte. */ - retval = i2c_smbus_read_byte_data(client, SMB_PROTOCOL_VERSION_ADDRESS); - if (retval < 0) { + while (time_before(jiffies, deadline)) { + + retval = i2c_smbus_read_byte_data(client, + SMB_PROTOCOL_VERSION_ADDRESS); + if (retval >= 0) { + retval++; + break; + } + dev_err(&client->dev, "failed to get SMBus version number!\n"); - return retval; + if (retval != -ENXIO) + break; + dev_warn(&client->dev, "sleeping to try again\n"); + fsleep(500); } - - return retval + 1; + dev_warn(&client->dev, "JAM: time to return %ums", jiffies_to_msecs(jiffies - before)); + return retval; } /* SMB block write - wrapper over ic2_smb_write_block */ -- 2.40.1.495.gc816e09b53d-goog