Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

regmap-i2c: Set regmap max raw r/w from quirks

Set regmap raw read/write from i2c quirks max read/write
so regmap_raw_read/write can split the access into chunks

Signed-off-by: Lucas Tanure <tanureal@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20210512135222.223203-1-tanureal@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Lucas Tanure and committed by
Mark Brown
ea030ca6 6efb943b

+42 -7
+38 -7
drivers/base/regmap/regmap-i2c.c
··· 306 306 static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c, 307 307 const struct regmap_config *config) 308 308 { 309 + const struct i2c_adapter_quirks *quirks; 310 + const struct regmap_bus *bus = NULL; 311 + struct regmap_bus *ret_bus; 312 + u16 max_read = 0, max_write = 0; 313 + 309 314 if (i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) 310 - return &regmap_i2c; 315 + bus = &regmap_i2c; 311 316 else if (config->val_bits == 8 && config->reg_bits == 8 && 312 317 i2c_check_functionality(i2c->adapter, 313 318 I2C_FUNC_SMBUS_I2C_BLOCK)) 314 - return &regmap_i2c_smbus_i2c_block; 319 + bus = &regmap_i2c_smbus_i2c_block; 315 320 else if (config->val_bits == 8 && config->reg_bits == 16 && 316 321 i2c_check_functionality(i2c->adapter, 317 322 I2C_FUNC_SMBUS_I2C_BLOCK)) 318 - return &regmap_i2c_smbus_i2c_block_reg16; 323 + bus = &regmap_i2c_smbus_i2c_block_reg16; 319 324 else if (config->val_bits == 16 && config->reg_bits == 8 && 320 325 i2c_check_functionality(i2c->adapter, 321 326 I2C_FUNC_SMBUS_WORD_DATA)) 322 327 switch (regmap_get_val_endian(&i2c->dev, NULL, config)) { 323 328 case REGMAP_ENDIAN_LITTLE: 324 - return &regmap_smbus_word; 329 + bus = &regmap_smbus_word; 330 + break; 325 331 case REGMAP_ENDIAN_BIG: 326 - return &regmap_smbus_word_swapped; 332 + bus = &regmap_smbus_word_swapped; 333 + break; 327 334 default: /* everything else is not supported */ 328 335 break; 329 336 } 330 337 else if (config->val_bits == 8 && config->reg_bits == 8 && 331 338 i2c_check_functionality(i2c->adapter, 332 339 I2C_FUNC_SMBUS_BYTE_DATA)) 333 - return &regmap_smbus_byte; 340 + bus = &regmap_smbus_byte; 334 341 335 - return ERR_PTR(-ENOTSUPP); 342 + if (!bus) 343 + return ERR_PTR(-ENOTSUPP); 344 + 345 + quirks = i2c->adapter->quirks; 346 + if (quirks) { 347 + if (quirks->max_read_len && 348 + (bus->max_raw_read == 0 || bus->max_raw_read > quirks->max_read_len)) 349 + max_read = quirks->max_read_len; 350 + 351 + if (quirks->max_write_len && 352 + (bus->max_raw_write == 0 || bus->max_raw_write > quirks->max_write_len)) 353 + max_write = quirks->max_write_len; 354 + 355 + if (max_read || max_write) { 356 + ret_bus = kmemdup(bus, sizeof(*bus), GFP_KERNEL); 357 + if (!ret_bus) 358 + return ERR_PTR(-ENOMEM); 359 + ret_bus->free_on_exit = true; 360 + ret_bus->max_raw_read = max_read; 361 + ret_bus->max_raw_write = max_write; 362 + bus = ret_bus; 363 + } 364 + } 365 + 366 + return bus; 336 367 } 337 368 338 369 struct regmap *__regmap_init_i2c(struct i2c_client *i2c,
+2
drivers/base/regmap/regmap.c
··· 1496 1496 mutex_destroy(&map->mutex); 1497 1497 kfree_const(map->name); 1498 1498 kfree(map->patch); 1499 + if (map->bus && map->bus->free_on_exit) 1500 + kfree(map->bus); 1499 1501 kfree(map); 1500 1502 } 1501 1503 EXPORT_SYMBOL_GPL(regmap_exit);
+2
include/linux/regmap.h
··· 502 502 * DEFAULT, BIG is assumed. 503 503 * @max_raw_read: Max raw read size that can be used on the bus. 504 504 * @max_raw_write: Max raw write size that can be used on the bus. 505 + * @free_on_exit: kfree this on exit of regmap 505 506 */ 506 507 struct regmap_bus { 507 508 bool fast_io; ··· 520 519 enum regmap_endian val_format_endian_default; 521 520 size_t max_raw_read; 522 521 size_t max_raw_write; 522 + bool free_on_exit; 523 523 }; 524 524 525 525 /*