Skip to content

Commit ede965f

Browse files
jonasjelonekAndi Shyti
authored andcommitted
i2c: rtl9300: remove broken SMBus Quick operation support
Remove the SMBus Quick operation from this driver because it is not natively supported by the hardware and is wrongly implemented in the driver. The I2C controllers in Realtek RTL9300 and RTL9310 are SMBus-compliant but there doesn't seem to be native support for the SMBus Quick operation. It is not explicitly mentioned in the documentation but looking at the registers which configure an SMBus transaction, one can see that the data length cannot be set to 0. This suggests that the hardware doesn't allow any SMBus message without data bytes (except for those it does on it's own, see SMBus Block Read). The current implementation of SMBus Quick operation passes a length of 0 (which is actually invalid). Before the fix of a bug in a previous commit, this led to a read operation of 16 bytes from any register (the one of a former transaction or any other value. This caused issues like soft-bricked SFP modules after a simple probe with i2cdetect which uses Quick by default. Running this with SFP modules whose EEPROM isn't write-protected, some of the initial bytes are overwritten because a 16-byte write operation is executed instead of a Quick Write. (This temporarily soft-bricked one of my DAC cables.) Because SMBus Quick operation is obviously not supported on these controllers (because a length of 0 cannot be set, even when no register address is set), remove that instead of claiming there is support. There also shouldn't be any kind of emulated 'Quick' which just does another kind of operation in the background. Otherwise, specific issues occur in case of a 'Quick' Write which actually writes unknown data to an unknown register. Fixes: c366be7 ("i2c: Add driver for the RTL9300 I2C controller") Cc: stable@vger.kernel.org # v6.13+ Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com> Tested-by: Sven Eckelmann <sven@narfation.org> Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz> Tested-by: Chris Packham <chris.packham@alliedtelesis.co.nz> # On RTL9302C based board Tested-by: Markus Stockhausen <markus.stockhausen@gmx.de> Signed-off-by: Andi Shyti <andi.shyti@kernel.org> Link: https://lore.kernel.org/r/20250831100457.3114-4-jelonek.jonas@gmail.com
1 parent 06418cb commit ede965f

File tree

1 file changed

+3
-12
lines changed

1 file changed

+3
-12
lines changed

drivers/i2c/busses/i2c-rtl9300.c

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -225,15 +225,6 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
225225
}
226226

227227
switch (size) {
228-
case I2C_SMBUS_QUICK:
229-
ret = rtl9300_i2c_config_xfer(i2c, chan, addr, 0);
230-
if (ret)
231-
goto out_unlock;
232-
ret = rtl9300_i2c_reg_addr_set(i2c, 0, 0);
233-
if (ret)
234-
goto out_unlock;
235-
break;
236-
237228
case I2C_SMBUS_BYTE:
238229
if (read_write == I2C_SMBUS_WRITE) {
239230
ret = rtl9300_i2c_config_xfer(i2c, chan, addr, 0);
@@ -315,9 +306,9 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
315306

316307
static u32 rtl9300_i2c_func(struct i2c_adapter *a)
317308
{
318-
return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
319-
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
320-
I2C_FUNC_SMBUS_BLOCK_DATA;
309+
return I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA |
310+
I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA |
311+
I2C_FUNC_SMBUS_I2C_BLOCK;
321312
}
322313

323314
static const struct i2c_algorithm rtl9300_i2c_algo = {

0 commit comments

Comments
 (0)