Patch "i2c: cadence: Support PEC for SMBus block read" has been added to the 4.19-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    i2c: cadence: Support PEC for SMBus block read

to the 4.19-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     i2c-cadence-support-pec-for-smbus-block-read.patch
and it can be found in the queue-4.19 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 4f7f6fb4fd2531c3de17544cf22c8672db33c36d
Author: Lars-Peter Clausen <lars@xxxxxxxxxx>
Date:   Sun Jul 17 16:52:44 2022 +0200

    i2c: cadence: Support PEC for SMBus block read
    
    [ Upstream commit 9fdf6d97f03035ad5298e2d1635036c74c2090ed ]
    
    SMBus packet error checking (PEC) is implemented by appending one
    additional byte of checksum data at the end of the message. This provides
    additional protection and allows to detect data corruption on the I2C bus.
    
    SMBus block reads support variable length reads. The first byte in the read
    message is the number of available data bytes.
    
    The combination of PEC and block read is currently not supported by the
    Cadence I2C driver.
     * When PEC is enabled the maximum transfer length for block reads
       increases from 33 to 34 bytes.
     * The I2C core smbus emulation layer relies on the driver updating the
       `i2c_msg` `len` field with the number of received bytes. The updated
       length is used when checking the PEC.
    
    Add support to the Cadence I2C driver for handling SMBus block reads with
    PEC. To determine the maximum transfer length uses the initial `len` value
    of the `i2c_msg`. When PEC is enabled this will be 2, when it is disabled
    it will be 1.
    
    Once a read transfer is done also increment the `len` field by the amount
    of received data bytes.
    
    This change has been tested with a UCM90320 PMBus power monitor, which
    requires block reads to access certain data fields, but also has PEC
    enabled by default.
    
    Fixes: df8eb5691c48 ("i2c: Add driver for Cadence I2C controller")
    Signed-off-by: Lars-Peter Clausen <lars@xxxxxxxxxx>
    Tested-by: Shubhrajyoti Datta <Shubhrajyoti.datta@xxxxxxx>
    Signed-off-by: Wolfram Sang <wsa@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c
index 512c61d31fe5..bce7bf93d62a 100644
--- a/drivers/i2c/busses/i2c-cadence.c
+++ b/drivers/i2c/busses/i2c-cadence.c
@@ -353,8 +353,13 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id)
 	ctrl_reg = cdns_i2c_readreg(CDNS_I2C_CR_OFFSET);
 	ctrl_reg |= CDNS_I2C_CR_RW | CDNS_I2C_CR_CLR_FIFO;
 
+	/*
+	 * Receive up to I2C_SMBUS_BLOCK_MAX data bytes, plus one message length
+	 * byte, plus one checksum byte if PEC is enabled. p_msg->len will be 2 if
+	 * PEC is enabled, otherwise 1.
+	 */
 	if (id->p_msg->flags & I2C_M_RECV_LEN)
-		id->recv_count = I2C_SMBUS_BLOCK_MAX + 1;
+		id->recv_count = I2C_SMBUS_BLOCK_MAX + id->p_msg->len;
 
 	id->curr_recv_count = id->recv_count;
 
@@ -540,6 +545,9 @@ static int cdns_i2c_process_msg(struct cdns_i2c *id, struct i2c_msg *msg,
 	if (id->err_status & CDNS_I2C_IXR_ARB_LOST)
 		return -EAGAIN;
 
+	if (msg->flags & I2C_M_RECV_LEN)
+		msg->len += min_t(unsigned int, msg->buf[0], I2C_SMBUS_BLOCK_MAX);
+
 	return 0;
 }
 



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux