Skip to content

Commit cad9ac0

Browse files
committed
i2c: tegra: Fix PEC support for SMBUS block read
jira LE-1907 Rebuild_History Non-Buildable kernel-5.14.0-284.30.1.el9_2 commit-author Akhil R <[email protected]> commit 9f85577 Update the msg->len value correctly for SMBUS block read. The discrepancy went unnoticed as msg->len is used in SMBUS transfers only when a PEC byte is added. Fixes: d7583c8 ("i2c: tegra: Add SMBus block read function") Signed-off-by: Akhil R <[email protected]> Acked-by: Thierry Reding <[email protected]> Signed-off-by: Wolfram Sang <[email protected]> (cherry picked from commit 9f85577) Signed-off-by: Jonathan Maple <[email protected]>
1 parent 675f72d commit cad9ac0

File tree

1 file changed

+27
-13
lines changed

1 file changed

+27
-13
lines changed

drivers/i2c/busses/i2c-tegra.c

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,10 @@ struct tegra_i2c_hw_feature {
242242
* @is_dvc: identifies the DVC I2C controller, has a different register layout
243243
* @is_vi: identifies the VI I2C controller, has a different register layout
244244
* @msg_complete: transfer completion notifier
245+
* @msg_buf_remaining: size of unsent data in the message buffer
246+
* @msg_len: length of message in current transfer
245247
* @msg_err: error code for completed message
246248
* @msg_buf: pointer to current message data
247-
* @msg_buf_remaining: size of unsent data in the message buffer
248249
* @msg_read: indicates that the transfer is a read access
249250
* @timings: i2c timings information like bus frequency
250251
* @multimaster_mode: indicates that I2C controller is in multi-master mode
@@ -277,6 +278,7 @@ struct tegra_i2c_dev {
277278

278279
struct completion msg_complete;
279280
size_t msg_buf_remaining;
281+
unsigned int msg_len;
280282
int msg_err;
281283
u8 *msg_buf;
282284

@@ -1160,7 +1162,7 @@ static void tegra_i2c_push_packet_header(struct tegra_i2c_dev *i2c_dev,
11601162
else
11611163
i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
11621164

1163-
packet_header = msg->len - 1;
1165+
packet_header = i2c_dev->msg_len - 1;
11641166

11651167
if (i2c_dev->dma_mode && !i2c_dev->msg_read)
11661168
*dma_buf++ = packet_header;
@@ -1233,20 +1235,32 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
12331235
return err;
12341236

12351237
i2c_dev->msg_buf = msg->buf;
1238+
i2c_dev->msg_len = msg->len;
12361239

1237-
/* The condition true implies smbus block read and len is already read */
1238-
if (msg->flags & I2C_M_RECV_LEN && end_state != MSG_END_CONTINUE)
1239-
i2c_dev->msg_buf = msg->buf + 1;
1240-
1241-
i2c_dev->msg_buf_remaining = msg->len;
12421240
i2c_dev->msg_err = I2C_ERR_NONE;
12431241
i2c_dev->msg_read = !!(msg->flags & I2C_M_RD);
12441242
reinit_completion(&i2c_dev->msg_complete);
12451243

1244+
/*
1245+
* For SMBUS block read command, read only 1 byte in the first transfer.
1246+
* Adjust that 1 byte for the next transfer in the msg buffer and msg
1247+
* length.
1248+
*/
1249+
if (msg->flags & I2C_M_RECV_LEN) {
1250+
if (end_state == MSG_END_CONTINUE) {
1251+
i2c_dev->msg_len = 1;
1252+
} else {
1253+
i2c_dev->msg_buf += 1;
1254+
i2c_dev->msg_len -= 1;
1255+
}
1256+
}
1257+
1258+
i2c_dev->msg_buf_remaining = i2c_dev->msg_len;
1259+
12461260
if (i2c_dev->msg_read)
1247-
xfer_size = msg->len;
1261+
xfer_size = i2c_dev->msg_len;
12481262
else
1249-
xfer_size = msg->len + I2C_PACKET_HEADER_SIZE;
1263+
xfer_size = i2c_dev->msg_len + I2C_PACKET_HEADER_SIZE;
12501264

12511265
xfer_size = ALIGN(xfer_size, BYTES_PER_FIFO_WORD);
12521266

@@ -1286,7 +1300,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
12861300
if (!i2c_dev->msg_read) {
12871301
if (i2c_dev->dma_mode) {
12881302
memcpy(i2c_dev->dma_buf + I2C_PACKET_HEADER_SIZE,
1289-
msg->buf, msg->len);
1303+
msg->buf, i2c_dev->msg_len);
12901304

12911305
dma_sync_single_for_device(i2c_dev->dev,
12921306
i2c_dev->dma_phys,
@@ -1343,7 +1357,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
13431357
i2c_dev->dma_phys,
13441358
xfer_size, DMA_FROM_DEVICE);
13451359

1346-
memcpy(i2c_dev->msg_buf, i2c_dev->dma_buf, msg->len);
1360+
memcpy(i2c_dev->msg_buf, i2c_dev->dma_buf, i2c_dev->msg_len);
13471361
}
13481362
}
13491363

@@ -1399,8 +1413,8 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
13991413
ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], MSG_END_CONTINUE);
14001414
if (ret)
14011415
break;
1402-
/* Set the read byte as msg len */
1403-
msgs[i].len = msgs[i].buf[0];
1416+
/* Set the msg length from first byte */
1417+
msgs[i].len += msgs[i].buf[0];
14041418
dev_dbg(i2c_dev->dev, "reading %d bytes\n", msgs[i].len);
14051419
}
14061420
ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], end_type);

0 commit comments

Comments
 (0)