From patchwork Mon May 9 12:44:31 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Abhishek Sahu X-Patchwork-Id: 619883 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3r3MYr1dHJz9sdm for ; Mon, 9 May 2016 22:45:52 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751883AbcEIMpO (ORCPT ); Mon, 9 May 2016 08:45:14 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:36183 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752190AbcEIMpM (ORCPT ); Mon, 9 May 2016 08:45:12 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 1420C6131E; Mon, 9 May 2016 12:45:11 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on pdx-caf-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=ALL_TRUSTED,BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.0 Received: from chewinlnx07.qualcomm.com (unknown [202.46.23.62]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: absahu@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 648F560222; Mon, 9 May 2016 12:45:06 +0000 (UTC) From: Abhishek Sahu To: agross@codeaurora.org Cc: sricharan@codeaurora.org, architt@codeaurora.org, linux-arm-msm@vger.kernel.org, ntelkar@codeaurora.org, linux-kernel@vger.kernel.org, andy.gross@linaro.org, linux-i2c@vger.kernel.org, dmaengine@vger.kernel.org, linux-arm-kernel@lists.infradead.org, wsa@the-dreams.de, Abhishek Sahu Subject: [PATCH 2/2] i2c: qup: Fixed the DMA segments length Date: Mon, 9 May 2016 18:14:31 +0530 Message-Id: <1462797871-8595-3-git-send-email-absahu@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1462797871-8595-1-git-send-email-absahu@codeaurora.org> References: <1462797871-8595-1-git-send-email-absahu@codeaurora.org> Sender: linux-i2c-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org 1. The current QCOM I2C driver code is failing for transfer length greater than 255. This is happening due to improper segments length as the I2C DMA segments can be maximum of 256 bytes. 2. The transfer length tlen was being initialized with 0 for 256 bytes, which is being passed for DMA mappings resulting in improper DMA mapping length. This patch fixes the above said problems by initializing the block count with the values calculated in qup_i2c_set_blk_data and calculating the remaining length for last DMA segment. Also, the block data length need to be decremented after each transfer. Additionally, this patch corrects the tlen assignment for DMA mapping. Signed-off-by: Abhishek Sahu --- drivers/i2c/busses/i2c-qup.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c index 8c2f1bc..6d6b7dc 100644 --- a/drivers/i2c/busses/i2c-qup.c +++ b/drivers/i2c/busses/i2c-qup.c @@ -651,23 +651,24 @@ static int qup_i2c_bam_do_xfer(struct qup_i2c_dev *qup, struct i2c_msg *msg, u8 *tags; while (idx < num) { - blocks = (msg->len + limit) / limit; - rem = msg->len % limit; tx_len = 0, len = 0, i = 0; qup->is_last = (idx == (num - 1)); qup_i2c_set_blk_data(qup, msg); + blocks = qup->blk.count; + rem = msg->len - (blocks - 1) * limit; + if (msg->flags & I2C_M_RD) { rx_nents += (blocks * 2) + 1; tx_nents += 1; while (qup->blk.pos < blocks) { - /* length set to '0' implies 256 bytes */ - tlen = (i == (blocks - 1)) ? rem : 0; + tlen = (i == (blocks - 1)) ? rem : limit; tags = &qup->start_tag.start[off + len]; len += qup_i2c_set_tags(tags, qup, msg, 1); + qup->blk.data_len -= tlen; /* scratch buf to read the start and len tags */ ret = qup_sg_set_buf(&qup->brx.sg[rx_buf++], @@ -706,9 +707,10 @@ static int qup_i2c_bam_do_xfer(struct qup_i2c_dev *qup, struct i2c_msg *msg, tx_nents += (blocks * 2); while (qup->blk.pos < blocks) { - tlen = (i == (blocks - 1)) ? rem : 0; + tlen = (i == (blocks - 1)) ? rem : limit; tags = &qup->start_tag.start[off + tx_len]; len = qup_i2c_set_tags(tags, qup, msg, 1); + qup->blk.data_len -= tlen; ret = qup_sg_set_buf(&qup->btx.sg[tx_buf++], tags,