Received: by 2002:a05:7412:6592:b0:d7:7d3a:4fe2 with SMTP id m18csp985407rdg; Fri, 11 Aug 2023 06:28:41 -0700 (PDT) X-Google-Smtp-Source: AGHT+IE4iG7b8kIqCRBL/cMDrkZTcb75uzNo9m9leB+lkPnDChykvePrv44X0lVZKOFUfp/1LiMf X-Received: by 2002:a05:6a20:9187:b0:13b:7848:9515 with SMTP id v7-20020a056a20918700b0013b78489515mr2577940pzd.13.1691760521540; Fri, 11 Aug 2023 06:28:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691760521; cv=none; d=google.com; s=arc-20160816; b=PHeDZSMrnwvj8qwHQlen/ucHyLJKnRgz5bayLkOnbelhlKMG/12SWA4ZqzUezARSwQ os4BZ/oNFeN6MoDygQCaP96b+41r9cfjsss1AZgx8wOCe5Mwe5wrhQza0EaqQA09zS1i zIsScMR2vdd8MEEw5UChmgLHsA4WwV1wgq5NRdamsogA7aEaL/mZ+fWpSSNg1u0YIBqo 1d5R7f7QGiURtgIYlTOPpc5HH3Rh6mdfN7pSzGRLeQPuehf2K2mFi2Urc2UI576mZw3/ XqjACEY0OFybyWWUPHeqcf2FDmW2b1Dg0a82ikSq+0PAxf6m/jJShtMvcp1s3XhK92nR SSvg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :cc:to:from:dkim-signature; bh=AhVnwGJ68D1Er7EJTToc3iXwRxrhSPiDwmkI0Rp62EY=; fh=J9HBSUH/5zT1TBMBY5vk09NCGySs+GdvnSJYX+6Rn+M=; b=N6BUHQ+0NW74rhs++GuQLwhvheglT6V6NaqDSj2GbYHVdEGh3DvG+wSY6wsmS15bDZ 7HJO6CjaiMPLFYgNJmsXzG82mjqCkzVJnrmDhGLXo6Lnp+GgXxFo5S20SNCkwnTUa8mS 7CNi8qVi6+NasofuFsi5yiD3sYOhTndjNqvAruHUxjWmwo8CMxN/Hoa/PVKIsYsmWySh AFSiSpjicw53oHEKRDyumfgn4uUkCD9bCaInRLHAGE1DrO0ZX/Qc5RDQMFyLslRvuPFQ mRclX0VekDWhAvHEJxpvLbgHIabhvLkMisZdUt84sjMUDBwCkdMfeMggc4qon0apYezh nvDQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sionneau.net header.s=selectormx4 header.b=LlpAinAp; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=sionneau.net Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id t184-20020a6381c1000000b00563dde13953si3446601pgd.739.2023.08.11.06.28.29; Fri, 11 Aug 2023 06:28:41 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@sionneau.net header.s=selectormx4 header.b=LlpAinAp; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=sionneau.net Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230160AbjHKMxM (ORCPT + 99 others); Fri, 11 Aug 2023 08:53:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33906 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229449AbjHKMxM (ORCPT ); Fri, 11 Aug 2023 08:53:12 -0400 X-Greylist: delayed 400 seconds by postgrey-1.37 at lindbergh.monkeyblade.net; Fri, 11 Aug 2023 05:53:10 PDT Received: from mx4.sionneau.net (mx4.sionneau.net [51.15.250.1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5CFDE109; Fri, 11 Aug 2023 05:53:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sionneau.net; s=selectormx4; t=1691757988; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:in-reply-to:in-reply-to:references:references; bh=AhVnwGJ68D1Er7EJTToc3iXwRxrhSPiDwmkI0Rp62EY=; b=LlpAinAp59spqpc8ohnGESsFJg0xwj+1DyiGslwbKsCiEHN/pFllgeuIZIOIdPOp0Fk63f bqMh129NCs59I6WprKV0m3BdHdXJ/6DbusWqkPddwvA6PNOVgDZZtYRamoc5WPHLLIQ57z yo0SrJbcgVW0umx+h/zYp4VS/UXpNZs= Received: from junon.lin.mbt.kalray.eu ( [217.181.231.53]) by mx4.sionneau.net (OpenSMTPD) with ESMTPSA id 1b942a1f (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Fri, 11 Aug 2023 12:46:28 +0000 (UTC) From: Yann Sionneau To: Jarkko Nikula , Andy Shevchenko , Mika Westerberg Cc: linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org, Yann Sionneau , Jonathan Borne Subject: [PATCH 2/2] i2c: designware: abort the transfer if receiving byte count of 0 Date: Fri, 11 Aug 2023 14:46:24 +0200 Message-Id: <20230811124624.12792-2-yann@sionneau.net> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230811124624.12792-1-yann@sionneau.net> References: <20230811124624.12792-1-yann@sionneau.net> X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Yann Sionneau Context: It's not clear whether Linux SMBus stack supports receiving 0 as byte count for SMBus read data block. Linux supports SMBus v2.0 spec, which says "The byte count may not be 0." Which does not seem very clear to me, as a non-native speaker. (Note that v3.0 of the spec says "The byte count may be 0.") Some drivers explicitly return -EPROTO in case of byte count 0. The issue: Regardless of whether Linux supports byte count of 0, if this happens the i2c-designware driver goes into an unrecoverable state holding SCL low if the IP is synthesized with the IC_EMPTYFIFO_HOLD_MASTER_EN parameter. The fix proposed by this patch: Abort the transfer by sending a STOP condition on the bus. Another approach would be to ignore the issue and let the driver timeout and disable the IP. The IP disabling is fixed by the previous patch in this patch series. The current patch just makes the recovery faster since Abort is sent directly without waiting for the timeout to happen. With this patch, disabling the IP is not necessary anymore. Co-developed-by: Jonathan Borne Signed-off-by: Jonathan Borne Tested-by: Yann Sionneau Signed-off-by: Yann Sionneau --- drivers/i2c/busses/i2c-designware-master.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c index b55c19b2515a..fa5301566bb1 100644 --- a/drivers/i2c/busses/i2c-designware-master.c +++ b/drivers/i2c/busses/i2c-designware-master.c @@ -499,6 +499,15 @@ i2c_dw_recv_len(struct dw_i2c_dev *dev, u8 len) return len; } +static void +i2c_dw_abort(struct dw_i2c_dev *dev) +{ + u32 enable; + + regmap_read(dev->map, DW_IC_ENABLE, &enable); + regmap_write(dev->map, DW_IC_ENABLE, enable | DW_IC_ENABLE_ABORT); +} + static void i2c_dw_read(struct dw_i2c_dev *dev) { @@ -526,11 +535,16 @@ i2c_dw_read(struct dw_i2c_dev *dev) u32 flags = msgs[dev->msg_read_idx].flags; regmap_read(dev->map, DW_IC_DATA_CMD, &tmp); + tmp &= DW_IC_DATA_CMD_DAT; + /* Ensure length byte is a valid value */ - if (flags & I2C_M_RECV_LEN && - (tmp & DW_IC_DATA_CMD_DAT) <= I2C_SMBUS_BLOCK_MAX && (tmp & DW_IC_DATA_CMD_DAT) > 0) { - len = i2c_dw_recv_len(dev, tmp); + if (flags & I2C_M_RECV_LEN) { + if ((tmp <= I2C_SMBUS_BLOCK_MAX) && (tmp != 0)) + len = i2c_dw_recv_len(dev, tmp); + else + i2c_dw_abort(dev); } + *buf++ = tmp; dev->rx_outstanding--; } -- 2.17.1