* @is_dvc: identifies the DVC I2C controller, has a different register layout
  * @is_vi: identifies the VI I2C controller, has a different register layout
  * @msg_complete: transfer completion notifier
+ * @msg_buf_remaining: size of unsent data in the message buffer
+ * @msg_len: length of message in current transfer
  * @msg_err: error code for completed message
  * @msg_buf: pointer to current message data
- * @msg_buf_remaining: size of unsent data in the message buffer
  * @msg_read: indicates that the transfer is a read access
  * @timings: i2c timings information like bus frequency
  * @multimaster_mode: indicates that I2C controller is in multi-master mode
 
        struct completion msg_complete;
        size_t msg_buf_remaining;
+       unsigned int msg_len;
        int msg_err;
        u8 *msg_buf;
 
        else
                i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
 
-       packet_header = msg->len - 1;
+       packet_header = i2c_dev->msg_len - 1;
 
        if (i2c_dev->dma_mode && !i2c_dev->msg_read)
                *dma_buf++ = packet_header;
                return err;
 
        i2c_dev->msg_buf = msg->buf;
+       i2c_dev->msg_len = msg->len;
 
-       /* The condition true implies smbus block read and len is already read */
-       if (msg->flags & I2C_M_RECV_LEN && end_state != MSG_END_CONTINUE)
-               i2c_dev->msg_buf = msg->buf + 1;
-
-       i2c_dev->msg_buf_remaining = msg->len;
        i2c_dev->msg_err = I2C_ERR_NONE;
        i2c_dev->msg_read = !!(msg->flags & I2C_M_RD);
        reinit_completion(&i2c_dev->msg_complete);
 
+       /*
+        * For SMBUS block read command, read only 1 byte in the first transfer.
+        * Adjust that 1 byte for the next transfer in the msg buffer and msg
+        * length.
+        */
+       if (msg->flags & I2C_M_RECV_LEN) {
+               if (end_state == MSG_END_CONTINUE) {
+                       i2c_dev->msg_len = 1;
+               } else {
+                       i2c_dev->msg_buf += 1;
+                       i2c_dev->msg_len -= 1;
+               }
+       }
+
+       i2c_dev->msg_buf_remaining = i2c_dev->msg_len;
+
        if (i2c_dev->msg_read)
-               xfer_size = msg->len;
+               xfer_size = i2c_dev->msg_len;
        else
-               xfer_size = msg->len + I2C_PACKET_HEADER_SIZE;
+               xfer_size = i2c_dev->msg_len + I2C_PACKET_HEADER_SIZE;
 
        xfer_size = ALIGN(xfer_size, BYTES_PER_FIFO_WORD);
 
        if (!i2c_dev->msg_read) {
                if (i2c_dev->dma_mode) {
                        memcpy(i2c_dev->dma_buf + I2C_PACKET_HEADER_SIZE,
-                              msg->buf, msg->len);
+                              msg->buf, i2c_dev->msg_len);
 
                        dma_sync_single_for_device(i2c_dev->dma_dev,
                                                   i2c_dev->dma_phys,
                                                i2c_dev->dma_phys,
                                                xfer_size, DMA_FROM_DEVICE);
 
-                       memcpy(i2c_dev->msg_buf, i2c_dev->dma_buf, msg->len);
+                       memcpy(i2c_dev->msg_buf, i2c_dev->dma_buf, i2c_dev->msg_len);
                }
        }
 
                        ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], MSG_END_CONTINUE);
                        if (ret)
                                break;
-                       /* Set the read byte as msg len */
-                       msgs[i].len = msgs[i].buf[0];
+                       /* Set the msg length from first byte */
+                       msgs[i].len += msgs[i].buf[0];
                        dev_dbg(i2c_dev->dev, "reading %d bytes\n", msgs[i].len);
                }
                ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], end_type);