Commit c330cb60 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull i2c fixes from Wolfram Sang:

 - hisi: update maintainership

 - fix several issues in rtl9300 xfer:
     - check message length boundaries
     - correct multi-byte value composition on write
     - increase polling timeout
     - fix block transfer protocol

* tag 'i2c-for-6.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  i2c: rtl9300: Add missing count byte for SMBus Block Ops
  i2c: rtl9300: Increase timeout for transfer polling
  i2c: rtl9300: Fix multi-byte I2C write
  i2c: rtl9300: Fix out-of-bounds bug in rtl9300_i2c_smbus_xfer
  MAINTAINERS: i2c: Update i2c_hisi entry
parents 69fd6b99 3dd22078
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -11025,7 +11025,7 @@ F: Documentation/admin-guide/perf/hns3-pmu.rst
F:	drivers/perf/hisilicon/hns3_pmu.c
HISILICON I2C CONTROLLER DRIVER
M:	Yicong Yang <yangyicong@hisilicon.com>
M:	Devyn Liu <liudingyuan@h-partners.com>
L:	linux-i2c@vger.kernel.org
S:	Maintained
W:	https://www.hisilicon.com
+12 −8
Original line number Diff line number Diff line
@@ -143,10 +143,10 @@ static int rtl9300_i2c_write(struct rtl9300_i2c *i2c, u8 *buf, int len)
		return -EIO;

	for (i = 0; i < len; i++) {
		if (i % 4 == 0)
			vals[i/4] = 0;
		vals[i/4] <<= 8;
		vals[i/4] |= buf[i];
		unsigned int shift = (i % 4) * 8;
		unsigned int reg = i / 4;

		vals[reg] |= buf[i] << shift;
	}

	return regmap_bulk_write(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_DATA_WORD0,
@@ -175,7 +175,7 @@ static int rtl9300_i2c_execute_xfer(struct rtl9300_i2c *i2c, char read_write,
		return ret;

	ret = regmap_read_poll_timeout(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_CTRL1,
				       val, !(val & RTL9300_I2C_MST_CTRL1_I2C_TRIG), 100, 2000);
				       val, !(val & RTL9300_I2C_MST_CTRL1_I2C_TRIG), 100, 100000);
	if (ret)
		return ret;

@@ -281,15 +281,19 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
		ret = rtl9300_i2c_reg_addr_set(i2c, command, 1);
		if (ret)
			goto out_unlock;
		ret = rtl9300_i2c_config_xfer(i2c, chan, addr, data->block[0]);
		if (data->block[0] < 1 || data->block[0] > I2C_SMBUS_BLOCK_MAX) {
			ret = -EINVAL;
			goto out_unlock;
		}
		ret = rtl9300_i2c_config_xfer(i2c, chan, addr, data->block[0] + 1);
		if (ret)
			goto out_unlock;
		if (read_write == I2C_SMBUS_WRITE) {
			ret = rtl9300_i2c_write(i2c, &data->block[1], data->block[0]);
			ret = rtl9300_i2c_write(i2c, &data->block[0], data->block[0] + 1);
			if (ret)
				goto out_unlock;
		}
		len = data->block[0];
		len = data->block[0] + 1;
		break;

	default: