From patchwork Sat Feb 3 07:58:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Abhishek Sahu X-Patchwork-Id: 10198377 X-Patchwork-Delegate: agross@codeaurora.org Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id A6D4760467 for ; Sat, 3 Feb 2018 07:59:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8104528F88 for ; Sat, 3 Feb 2018 07:59:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 75D7628FCA; Sat, 3 Feb 2018 07:59:17 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0A97328FCC for ; Sat, 3 Feb 2018 07:59:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752089AbeBCH7L (ORCPT ); Sat, 3 Feb 2018 02:59:11 -0500 Received: from smtp.codeaurora.org ([198.145.29.96]:35606 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751956AbeBCH6t (ORCPT ); Sat, 3 Feb 2018 02:58:49 -0500 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id A49676081C; Sat, 3 Feb 2018 07:58:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1517644728; bh=UKDYCeTdoFcnsPnAKsglAy7BF59xMpCNg5QS12m02VU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BCF8ZLoMuhBADsKxPG2Ij/A9dDhU3NoYMndV9Fy0jrRgjMlYaJW4lCsWCjsTK7rFA tO7IQp0Fbdwpl0k8sZtl842OHeQdJB4sI6QT3t0TN9Pr5LdnKWBmvgej+RG3Sngsn+ loQ/eEmUhAkHXuu+Ss37QXK9swJcGQE9sXEpqBp4= Received: from absahu-linux.qualcomm.com (blr-c-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.19.19]) (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 75EC96090E; Sat, 3 Feb 2018 07:58:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1517644727; bh=UKDYCeTdoFcnsPnAKsglAy7BF59xMpCNg5QS12m02VU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RtaznYDRDoqW2LTRLla58lgagwTv7V/dKLKcRwoADAGgi1GfgNdoS3A++Kipv19X/ F4rZPgqzkojUUcplWNJLdNLhCFWyxdL08+TCTUFDDDqd8QX79dJIIduH6ahr1+3eiM ksLJurn8jDQCyGStkmuOLq0DjbIEaSwklkybQfjM= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 75EC96090E Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=absahu@codeaurora.org From: Abhishek Sahu To: Andy Gross , Wolfram Sang Cc: David Brown , Sricharan R , linux-arm-msm@vger.kernel.org, linux-soc@vger.kernel.org, linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org, Abhishek Sahu Subject: [PATCH 06/12] i2c: qup: proper error handling for i2c error in BAM mode Date: Sat, 3 Feb 2018 13:28:11 +0530 Message-Id: <1517644697-30806-7-git-send-email-absahu@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1517644697-30806-1-git-send-email-absahu@codeaurora.org> References: <1517644697-30806-1-git-send-email-absahu@codeaurora.org> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Currently the i2c error handling in BAM mode is not working properly in stress condition. 1. After an error, the FIFO are being written with FLUSH and EOT tags which should not be required since already these tags have been written in BAM descriptor itself. 2. QUP state is being moved to RESET in IRQ handler in case of error. When QUP HW encounters an error in BAM mode then it moves the QUP STATE to PAUSE state. In this case, I2C_FLUSH command needs to be executed while moving to RUN_STATE by writing to the QUP_STATE register with the I2C_FLUSH bit set to 1. 3. In Error case, sometimes, QUP generates more than one interrupt which will trigger the complete again. After an error, the flush operation will be scheduled after doing reinit_completion which should be triggered by BAM IRQ callback. If the second QUP IRQ comes during this time then it will call the complete and the transfer function will assume the all the BAM HW descriptors have been completed. 4. The release DMA is being called after each error which will free the DMA tx and rx channels. The error like NACK is very common in I2C transfer and every time this will be overhead. Now, since the error handling is proper so this release channel can be completely avoided. Signed-off-by: Abhishek Sahu Reviewed-by: Austin Christ --- drivers/i2c/busses/i2c-qup.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c index 094be6a..6227a5c 100644 --- a/drivers/i2c/busses/i2c-qup.c +++ b/drivers/i2c/busses/i2c-qup.c @@ -228,9 +228,24 @@ static irqreturn_t qup_i2c_interrupt(int irq, void *dev) if (bus_err) writel(bus_err, qup->base + QUP_I2C_STATUS); + /* + * Check for BAM mode and returns if already error has come for current + * transfer. In Error case, sometimes, QUP generates more than one + * interrupt. + */ + if (qup->use_dma && (qup->qup_err || qup->bus_err)) + return IRQ_HANDLED; + /* Reset the QUP State in case of error */ if (qup_err || bus_err) { - writel(QUP_RESET_STATE, qup->base + QUP_STATE); + /* + * Don’t reset the QUP state in case of BAM mode. The BAM + * flush operation needs to be scheduled in transfer function + * which will clear the remaining schedule descriptors in BAM + * HW FIFO and generates the BAM interrupt. + */ + if (!qup->use_dma) + writel(QUP_RESET_STATE, qup->base + QUP_STATE); goto done; } @@ -841,20 +856,12 @@ static int qup_i2c_bam_do_xfer(struct qup_i2c_dev *qup, struct i2c_msg *msg, goto desc_err; } - if (rx_buf) - writel(QUP_BAM_INPUT_EOT, - qup->base + QUP_OUT_FIFO_BASE); - - writel(QUP_BAM_FLUSH_STOP, qup->base + QUP_OUT_FIFO_BASE); - qup_i2c_flush(qup); /* wait for remaining interrupts to occur */ if (!wait_for_completion_timeout(&qup->xfer, HZ)) dev_err(qup->dev, "flush timed out\n"); - qup_i2c_rel_dma(qup); - ret = (qup->bus_err & QUP_I2C_NACK_FLAG) ? -ENXIO : -EIO; }