From patchwork Tue Jul 27 11:15:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Codrin Ciubotariu X-Patchwork-Id: 12402545 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.5 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E9EEDC4338F for ; Tue, 27 Jul 2021 11:19:07 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B15046054F for ; Tue, 27 Jul 2021 11:19:07 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org B15046054F Authentication-Results: mail.kernel.org; dmarc=fail (p=quarantine dis=none) header.from=microchip.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=quhnkYOZp2Cg12BXoSEtNKVRhba72lXwAQIw8O0OiaY=; b=exFxpBL2HcrIsM 8v++G9aIDnKLHOcIbmuAYd/c9BbmIvkeZslIFMVVsPcicuN5I6nVg9HWxpoCDZBeb3bYepRhueG8p oega6xZdDbZm2Hh4Jzleu9PQ4c+QA8hogMFHbB4knfYutkIZJ8/JRKvwpQLqQodGpcIOjpPTtVrwT ljsu25WTD/jlUhyCf4vDpgCh6WH52f3VP+Gq691RTOVPZaK8IX7wZ5ozPWkIa6GfPlYuvfP12xU92 qCYF4L/+sTRLtOyu1jwNWBuadgjhIVEAuXuHcygPuLQSZUtGCx2IS4CnKjFwtRqF2ijXaixkUn+1N 10JfsWrjOQY0C6wFonlg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1m8L4i-00Eaf0-DR; Tue, 27 Jul 2021 11:16:40 +0000 Received: from esa.microchip.iphmx.com ([68.232.153.233]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1m8L4M-00EaZK-1g for linux-arm-kernel@lists.infradead.org; Tue, 27 Jul 2021 11:16:19 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1627384577; x=1658920577; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=qvjts8FHdUOt3MATa6RJ6cMOmBfjlcKN7y0bK5Yzco4=; b=rqZVVzlwVvakAwB/Ju3GpkrDGtlFoCCnhCTsSyvHDe6XBJmxFA9rSnK/ 7WiKg6D42XH9XTleDxOmN5mjGgjjmPe9Ua9gZmz4H+Pokr8L1rJ0djwBg TzledjVWuQjFEQe+0lDKU/g9nPGbtzF+iCyIUsVAE5comST6PD0TKrroi BKubeVJNI2Vx5FE67IO3ZutWR0H+jul+EgobwbWUap6sYVoXl6mdmj7KU L0oKpgI120EujukoARTMnpOnGnuHBeYPxT1CZY6ZUSBmNSFwwlAe/NMFk TcbdpTNhuAQprq7ZMLtOWHrQ9N66wUf0V7430v9hvXtkHcV839C8/qB4r A==; IronPort-SDR: WtDyj/QDN48Sivi6Ul4lXOOi3UKaNVkCHPYxgbY3F0Zh90lwCtuXquHe/h38v3JhVqYjwvj90y zYgiMKW0yrO1Bq/69HB1qGFYOSnwFES7kF9+TAzbGd/M1nFMlzZQwjVnPinNHmVgpAHEn+V+2B bfP+s3u6JuxXUnb5aqFBYh2mzvoPSwD1PVza0tlE4SAD76tBkU6QJ73Eea4TsPL7aHlVzOMo8/ xIznVYLS0QtYCkyTr7dgNgVTZP47H+LI+IOtXqTgUoSyXyFgZ6SzUSE62orTCCf9iVcuOZhSAA u4uKGmhxhZIheHjAWCr/GvoU X-IronPort-AV: E=Sophos;i="5.84,273,1620716400"; d="scan'208";a="137698107" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa1.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 27 Jul 2021 04:16:15 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2176.2; Tue, 27 Jul 2021 04:16:15 -0700 Received: from rob-ult-m19940.amer.actel.com (10.10.115.15) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2176.2 via Frontend Transport; Tue, 27 Jul 2021 04:16:12 -0700 From: Codrin Ciubotariu To: , , Subject: [PATCH 2/3] i2c: at91: keep the controller disabled when it is not used Date: Tue, 27 Jul 2021 14:15:53 +0300 Message-ID: <20210727111554.1338832-3-codrin.ciubotariu@microchip.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210727111554.1338832-1-codrin.ciubotariu@microchip.com> References: <20210727111554.1338832-1-codrin.ciubotariu@microchip.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210727_041618_217880_00E45675 X-CRM114-Status: GOOD ( 17.26 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alexandre.belloni@bootlin.com, wsa@kernel.org, mhoffman@lightlink.com, ludovic.desroches@microchip.com, khali@linux-fr.org, andrew@sanpeople.com, Codrin Ciubotariu Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org The controller (master mode) should be disabled when it is not used, to avoid potential glitches on the bus. The controller must be disabled only when the controller is not running. This fixes an issue on Microchip's SAMA5D4 platform when pinctrl changes the I2C's pin states between GPIO and I2C, done when GPIO recovery is used. Fixes: 813e30e9ab91 ("i2c: New Atmel AT91 bus driver") Signed-off-by: Codrin Ciubotariu --- drivers/i2c/busses/i2c-at91-master.c | 34 ++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-at91-master.c b/drivers/i2c/busses/i2c-at91-master.c index 0352dc09d697..1f91829438fd 100644 --- a/drivers/i2c/busses/i2c-at91-master.c +++ b/drivers/i2c/busses/i2c-at91-master.c @@ -38,7 +38,7 @@ void at91_init_twi_bus_master(struct at91_twi_dev *dev) /* FIFO should be enabled immediately after the software reset */ if (dev->fifo_size) at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_FIFOEN); - at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_MSEN); + at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_MSDIS); at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_SVDIS); at91_twi_write(dev, AT91_TWI_CWGR, dev->twi_cwgr_reg); @@ -593,7 +593,6 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev) if (time_left == 0) { dev->transfer_status |= at91_twi_read(dev, AT91_TWI_SR); dev_err(dev->dev, "controller timed out\n"); - at91_init_twi_bus(dev); ret = -ETIMEDOUT; goto error; } @@ -642,6 +641,26 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev) return ret; } +static void at91_twi_disable(struct at91_twi_dev *dev) +{ + /* return if previous operation is completed */ + if (!(at91_twi_read(dev, AT91_TWI_SR) & AT91_TWI_TXCOMP)) { + /* wait for previous command to complete before disabling the controller */ + dev_dbg(dev->dev, "wait for command to complete...\n"); + reinit_completion(&dev->cmd_complete); + dev->transfer_status = 0; + at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_TXCOMP); + wait_for_completion_timeout(&dev->cmd_complete, dev->adapter.timeout); + if (!(dev->transfer_status & AT91_TWI_TXCOMP)) { + dev_dbg(dev->dev, "IP still busy, resetting the controller...\n"); + at91_init_twi_bus(dev); + return; + } + } + + at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_MSDIS); +} + static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num) { struct at91_twi_dev *dev = i2c_get_adapdata(adap); @@ -656,6 +675,8 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num) if (ret < 0) goto out; + at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_MSEN); + if (num == 2) { int internal_address = 0; int i; @@ -699,13 +720,22 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num) ret = at91_do_twi_transfer(dev); if (ret < 0) { + /* disable controller before using GPIO recovery */ + if (!dev->pdata->has_clear_cmd) + at91_twi_disable(dev); + /* * some faulty I2C slave devices might hold SDA down; * we can send a bus clear command, hoping that the pins will be * released */ i2c_recover_bus(&dev->adapter); + + /* disable controller if not disabled before */ + if (dev->pdata->has_clear_cmd) + at91_twi_disable(dev); } else { + at91_twi_disable(dev); ret = num; }