mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
regmap: Fixes for v7.1
There's couple of patches here that came in since my pull request:
- What is effectively a quirk for shoehorning support for a wider range
of I2C regmaps on weirdly restricted SMBus controllers.
- One minor fix for a memory leak on in error handling in the dummy
driver used by the KUnit tests.
-----BEGIN PGP SIGNATURE-----
iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmnrgSsACgkQJNaLcl1U
h9AfoAf/TYndFyEmvFiaG41OECKDlhRdtX43WS2ulFZDXjeAhRJlLecBVwHN8o5c
RLMLvDs07nBr0arYCQl/MOvKZEUorT2Ka0eCI3RL95K0AitzF/taNcXTwEtnuAOT
lBRBOSHsbR1+X2WJWhv56M0oK01//Hm9KG1CywiG1WzAXt708UWkVGMoB+T5AGw0
RU12YIJCVcoX6CfHlwgFm8tZxk8GeaEKVy6tPwQ23SYt/trlqJpBqDCcTYAlVGzW
hzqwgq1+/zFs4AH1zdk55Me0g82yC/linfgT5tfouKq3CIdEDUruYdPk/1vbJBdx
mMrRovslNx+IEG61v8fnub0U6eM4iw==
=1GRM
-----END PGP SIGNATURE-----
Merge tag 'regmap-fix-v7.1-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap
Pull regmap fixes from Mark Brown:
"There's couple of patches here that came in since my pull request:
- What is effectively a quirk for shoehorning support for a wider
range of I2C regmaps on weirdly restricted SMBus controllers
- One minor fix for a memory leak on in error handling in the dummy
driver used by the KUnit tests"
* tag 'regmap-fix-v7.1-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap:
regmap: ram: fix memory leaks in __regmap_init_ram() on error
regmap-i2c: add SMBus byte/word reg16 bus for adapters lacking I2C_FUNC_I2C
This commit is contained in:
commit
6e2d43100c
|
|
@ -303,6 +303,50 @@ static const struct regmap_bus regmap_i2c_smbus_i2c_block_reg16 = {
|
|||
.max_raw_write = I2C_SMBUS_BLOCK_MAX - 2,
|
||||
};
|
||||
|
||||
/*
|
||||
* SMBus byte/word reg16 support for adapters that have SMBUS_BYTE_DATA
|
||||
* and SMBUS_WORD_DATA but lack I2C_FUNC_I2C and I2C_FUNC_SMBUS_I2C_BLOCK,
|
||||
* such as the AMD PIIX4.
|
||||
*
|
||||
* READ: set 16-bit EEPROM address via write_byte_data(addr_lo, addr_hi),
|
||||
* then sequentially read bytes via read_byte() (EEPROM auto-
|
||||
* increments the address pointer). Same as the I2C-block reg16
|
||||
* read path above.
|
||||
*
|
||||
* WRITE: encode the low address byte and data into a word transaction:
|
||||
* write_word_data(addr_hi, (data_byte << 8) | addr_lo).
|
||||
* Only single-byte writes are supported (one value per transaction).
|
||||
*/
|
||||
static int regmap_smbus_word_write_reg16(void *context, const void *data,
|
||||
size_t count)
|
||||
{
|
||||
struct device *dev = context;
|
||||
struct i2c_client *i2c = to_i2c_client(dev);
|
||||
u8 addr_hi, addr_lo, val;
|
||||
|
||||
/*
|
||||
* data layout: [addr_hi, addr_lo, val0, val1, ...].
|
||||
* Only single-byte value writes are supported; multi-byte would
|
||||
* require raw I2C (or repeated word writes with incrementing address).
|
||||
*/
|
||||
if (count != 3)
|
||||
return -EINVAL;
|
||||
|
||||
addr_hi = ((u8 *)data)[0];
|
||||
addr_lo = ((u8 *)data)[1];
|
||||
val = ((u8 *)data)[2];
|
||||
|
||||
return i2c_smbus_write_word_data(i2c, addr_hi,
|
||||
cpu_to_le16(((u16)val << 8) | addr_lo));
|
||||
}
|
||||
|
||||
static const struct regmap_bus regmap_smbus_byte_word_reg16 = {
|
||||
.write = regmap_smbus_word_write_reg16,
|
||||
.read = regmap_i2c_smbus_i2c_read_reg16,
|
||||
.max_raw_read = I2C_SMBUS_BLOCK_MAX - 2,
|
||||
.max_raw_write = 1,
|
||||
};
|
||||
|
||||
static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c,
|
||||
const struct regmap_config *config)
|
||||
{
|
||||
|
|
@ -321,6 +365,11 @@ static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c,
|
|||
i2c_check_functionality(i2c->adapter,
|
||||
I2C_FUNC_SMBUS_I2C_BLOCK))
|
||||
bus = ®map_i2c_smbus_i2c_block_reg16;
|
||||
else if (config->val_bits == 8 && config->reg_bits == 16 &&
|
||||
i2c_check_functionality(i2c->adapter,
|
||||
I2C_FUNC_SMBUS_BYTE_DATA |
|
||||
I2C_FUNC_SMBUS_WORD_DATA))
|
||||
bus = ®map_smbus_byte_word_reg16;
|
||||
else if (config->val_bits == 16 && config->reg_bits == 8 &&
|
||||
i2c_check_functionality(i2c->adapter,
|
||||
I2C_FUNC_SMBUS_WORD_DATA))
|
||||
|
|
|
|||
|
|
@ -71,11 +71,17 @@ struct regmap *__regmap_init_ram(struct device *dev,
|
|||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
data->written = kzalloc_objs(bool, config->max_register + 1);
|
||||
if (!data->written)
|
||||
if (!data->written) {
|
||||
kfree(data->read);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
map = __regmap_init(dev, ®map_ram, data, config,
|
||||
lock_key, lock_name);
|
||||
if (IS_ERR(map)) {
|
||||
kfree(data->read);
|
||||
kfree(data->written);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user