Revert "power: supply: sbs-battery: simplify read_read_string_data"
authorSebastian Reichel <sre@kernel.org>
Tue, 2 Jun 2020 14:49:08 +0000 (16:49 +0200)
committerSebastian Reichel <sre@kernel.org>
Tue, 2 Jun 2020 15:08:33 +0000 (17:08 +0200)
The commit is a nice cleanup, but breaks booting on exynos5 based
chromebooks. It's seems to come down to exynos5's i2c driver not
implementing I2C_FUNC_SMBUS_READ_BLOCK_DATA. It's not yet clear
why that breaks boot / massively slows it down when userspace
starts, so revert the problematic patch.

This reverts commit c4b12a2f3f3de670f6be5e96092a2cab0b877f1a.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
drivers/power/supply/sbs-battery.c

index 00dfd9e..83b9924 100644 (file)
@@ -267,32 +267,66 @@ static int sbs_read_string_data(struct i2c_client *client, u8 address,
                                char *values)
 {
        struct sbs_info *chip = i2c_get_clientdata(client);
-       int retries = chip->i2c_retry_count;
-       s32 ret = 0;
+       s32 ret = 0, block_length = 0;
+       int retries_length, retries_block;
+       u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1];
 
+       retries_length = chip->i2c_retry_count;
+       retries_block = chip->i2c_retry_count;
+
+       /* Adapter needs to support these two functions */
        if (!i2c_check_functionality(client->adapter,
-                                    I2C_FUNC_SMBUS_READ_BLOCK_DATA)) {
+                                    I2C_FUNC_SMBUS_BYTE_DATA |
+                                    I2C_FUNC_SMBUS_I2C_BLOCK)){
                return -ENODEV;
        }
 
+       /* Get the length of block data */
+       while (retries_length > 0) {
+               ret = i2c_smbus_read_byte_data(client, address);
+               if (ret >= 0)
+                       break;
+               retries_length--;
+       }
+
+       if (ret < 0) {
+               dev_dbg(&client->dev,
+                       "%s: i2c read at address 0x%x failed\n",
+                       __func__, address);
+               return ret;
+       }
+
+       /* block_length does not include NULL terminator */
+       block_length = ret;
+       if (block_length > I2C_SMBUS_BLOCK_MAX) {
+               dev_err(&client->dev,
+                       "%s: Returned block_length is longer than 0x%x\n",
+                       __func__, I2C_SMBUS_BLOCK_MAX);
+               return -EINVAL;
+       }
+
        /* Get the block data */
-       while (retries > 0) {
-               ret = i2c_smbus_read_block_data(client, address, values);
+       while (retries_block > 0) {
+               ret = i2c_smbus_read_i2c_block_data(
+                               client, address,
+                               block_length + 1, block_buffer);
                if (ret >= 0)
                        break;
-               retries--;
+               retries_block--;
        }
 
        if (ret < 0) {
-               dev_dbg(&client->dev, "%s: failed to read block 0x%x: %d\n",
-                       __func__, address, ret);
+               dev_dbg(&client->dev,
+                       "%s: i2c read at address 0x%x failed\n",
+                       __func__, address);
                return ret;
        }
 
-       /* add string termination */
-       values[ret] = '\0';
+       /* block_buffer[0] == block_length */
+       memcpy(values, block_buffer + 1, block_length);
+       values[block_length] = '\0';
 
-       return 0;
+       return ret;
 }
 
 static int sbs_write_word_data(struct i2c_client *client, u8 address,
@@ -514,7 +548,14 @@ static int sbs_get_battery_property(struct i2c_client *client,
 static int sbs_get_battery_string_property(struct i2c_client *client,
        int reg_offset, enum power_supply_property psp, char *val)
 {
-       return sbs_read_string_data(client, sbs_data[reg_offset].addr, val);
+       s32 ret;
+
+       ret = sbs_read_string_data(client, sbs_data[reg_offset].addr, val);
+
+       if (ret < 0)
+               return ret;
+
+       return 0;
 }
 
 static void  sbs_unit_adjustment(struct i2c_client *client,