Skip to content

Commit 972eabb

Browse files
committed
Revert "power: supply: sbs-battery: simplify read_read_string_data"
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 c4b12a2. Signed-off-by: Sebastian Reichel <[email protected]>
1 parent cf1eb32 commit 972eabb

File tree

1 file changed

+53
-12
lines changed

1 file changed

+53
-12
lines changed

drivers/power/supply/sbs-battery.c

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -267,32 +267,66 @@ static int sbs_read_string_data(struct i2c_client *client, u8 address,
267267
char *values)
268268
{
269269
struct sbs_info *chip = i2c_get_clientdata(client);
270-
int retries = chip->i2c_retry_count;
271-
s32 ret = 0;
270+
s32 ret = 0, block_length = 0;
271+
int retries_length, retries_block;
272+
u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1];
272273

274+
retries_length = chip->i2c_retry_count;
275+
retries_block = chip->i2c_retry_count;
276+
277+
/* Adapter needs to support these two functions */
273278
if (!i2c_check_functionality(client->adapter,
274-
I2C_FUNC_SMBUS_READ_BLOCK_DATA)) {
279+
I2C_FUNC_SMBUS_BYTE_DATA |
280+
I2C_FUNC_SMBUS_I2C_BLOCK)){
275281
return -ENODEV;
276282
}
277283

284+
/* Get the length of block data */
285+
while (retries_length > 0) {
286+
ret = i2c_smbus_read_byte_data(client, address);
287+
if (ret >= 0)
288+
break;
289+
retries_length--;
290+
}
291+
292+
if (ret < 0) {
293+
dev_dbg(&client->dev,
294+
"%s: i2c read at address 0x%x failed\n",
295+
__func__, address);
296+
return ret;
297+
}
298+
299+
/* block_length does not include NULL terminator */
300+
block_length = ret;
301+
if (block_length > I2C_SMBUS_BLOCK_MAX) {
302+
dev_err(&client->dev,
303+
"%s: Returned block_length is longer than 0x%x\n",
304+
__func__, I2C_SMBUS_BLOCK_MAX);
305+
return -EINVAL;
306+
}
307+
278308
/* Get the block data */
279-
while (retries > 0) {
280-
ret = i2c_smbus_read_block_data(client, address, values);
309+
while (retries_block > 0) {
310+
ret = i2c_smbus_read_i2c_block_data(
311+
client, address,
312+
block_length + 1, block_buffer);
281313
if (ret >= 0)
282314
break;
283-
retries--;
315+
retries_block--;
284316
}
285317

286318
if (ret < 0) {
287-
dev_dbg(&client->dev, "%s: failed to read block 0x%x: %d\n",
288-
__func__, address, ret);
319+
dev_dbg(&client->dev,
320+
"%s: i2c read at address 0x%x failed\n",
321+
__func__, address);
289322
return ret;
290323
}
291324

292-
/* add string termination */
293-
values[ret] = '\0';
325+
/* block_buffer[0] == block_length */
326+
memcpy(values, block_buffer + 1, block_length);
327+
values[block_length] = '\0';
294328

295-
return 0;
329+
return ret;
296330
}
297331

298332
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,
514548
static int sbs_get_battery_string_property(struct i2c_client *client,
515549
int reg_offset, enum power_supply_property psp, char *val)
516550
{
517-
return sbs_read_string_data(client, sbs_data[reg_offset].addr, val);
551+
s32 ret;
552+
553+
ret = sbs_read_string_data(client, sbs_data[reg_offset].addr, val);
554+
555+
if (ret < 0)
556+
return ret;
557+
558+
return 0;
518559
}
519560

520561
static void sbs_unit_adjustment(struct i2c_client *client,

0 commit comments

Comments
 (0)