From patchwork Tue May 21 15:11:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabrice Gasnier X-Patchwork-Id: 13669500 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 44CBBC25B7C for ; Tue, 21 May 2024 15:12:19 +0000 (UTC) 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:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Date:Subject:CC :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=DlzD3UVjH5Nkagz4rYPeLU7NucGM2FLXcPzUhKtV5C4=; b=L7thzBz0vspfpe FRGf9p6+H/Q2pyLRkDJeV1E1KpUKpAjjfrVlObWcB2WZM1BU4TCWhFr4yJzT5sFIgU7oZXGrx57ge NKl4ccPei8bGSNY5ffOEM3NZfsSZketbIBKIadHe/PFnjHVSumMpnkV0QTxzpaIxqRdGq4ZAf4T0J 81c5Yyp11ZP9Z2RBa1kifpWUakkE2WLrxoNHk3moRQFdyd7OrRpuYuOMEEcMXHlEN/roPglID9OSI D+VRvNsiG5yhr0lrD/rGNKK8ukevhBsIDawng/5DOx9MV37OdVY+Z+dyhG/s7F55Ks2ZobhvLallq /wuvMPP28EvO8k9So38A==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1s9R9r-00000000IoH-1V9w; Tue, 21 May 2024 15:12:07 +0000 Received: from mx07-00178001.pphosted.com ([185.132.182.106]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1s9R9n-00000000Imv-0Mr3 for linux-arm-kernel@lists.infradead.org; Tue, 21 May 2024 15:12:05 +0000 Received: from pps.filterd (m0288072.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 44LDpiHh028512; Tue, 21 May 2024 17:11:49 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h= from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding:content-type; s=selector1; bh=/FEvlAQ usilGdNjTRD3PN3O7G4HvNhMpAzyobKWFMJ8=; b=RzUe5abH98tY6GRCtWl7ubG AVSey2r/LDF6N+YK3U9A6eXRwP250dihFM5bZPJyA8GFYLqmHfJw9PIKPzA+c6XO hsxsg7pZX2MobxHpYMLu0JJfYmk2A0Zfcwed1cu5CHvTXAf4mJFjTX7O7k2R86GH L2xVp1KMZFbDLfjGYJvc0PfKTEYBA5Co7pBRHfH5bvYvO5abtZikcO89T9h7nkHl Ud0Tcb3BiR6DT5kAQ2Fa+BflikB3eN9VwGpl7QVi8NjQrKT0FI9s9Y3rfR+WYKtd CHCaX4Ai6XP9sS9EbvoekG1iuGsLPegHdsJ7hLjtGyUE9jkm4LHzU32ByQJARdQ= = Received: from beta.dmz-ap.st.com (beta.dmz-ap.st.com [138.198.100.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 3y8vqh8cag-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 21 May 2024 17:11:48 +0200 (MEST) Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-ap.st.com (STMicroelectronics) with ESMTP id 1BCFF4002D; Tue, 21 May 2024 17:11:43 +0200 (CEST) Received: from Webmail-eu.st.com (shfdag1node2.st.com [10.75.129.70]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 220332194C7; Tue, 21 May 2024 17:11:17 +0200 (CEST) Received: from localhost (10.252.1.80) by SHFDAG1NODE2.st.com (10.75.129.70) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Tue, 21 May 2024 17:11:16 +0200 From: Fabrice Gasnier To: , CC: , , , , Subject: [PATCH] usb: ucsi: stm32: fix command completion handling Date: Tue, 21 May 2024 17:11:09 +0200 Message-ID: <20240521151109.3078775-1-fabrice.gasnier@foss.st.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-Originating-IP: [10.252.1.80] X-ClientProxiedBy: SAFCAS1NODE1.st.com (10.75.90.11) To SHFDAG1NODE2.st.com (10.75.129.70) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.650,FMLib:17.12.28.16 definitions=2024-05-21_09,2024-05-21_01,2024-05-17_01 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240521_081203_778503_84AE9828 X-CRM114-Status: GOOD ( 15.29 ) 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: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Sometimes errors are seen, when doing DR swap, like: [ 24.672481] ucsi-stm32g0-i2c 0-0035: UCSI_GET_PDOS failed (-5) [ 24.720188] ucsi-stm32g0-i2c 0-0035: ucsi_handle_connector_change: GET_CONNECTOR_STATUS failed (-5) There may be some race, which lead to read CCI, before the command complete flag is set, hence returning -EIO. Similar fix has been done also in ucsi_acpi [1]. In case of a spurious or otherwise delayed notification it is possible that CCI still reports the previous completion. The UCSI spec is aware of this and provides two completion bits in CCI, one for normal commands and one for acks. As acks and commands alternate the notification handler can determine if the completion bit is from the current command. To fix this add the ACK_PENDING bit for ucsi_stm32g0 and only complete commands if the completion bit matches. [1] https://lore.kernel.org/lkml/20240121204123.275441-3-lk@c--e.de/ Fixes: 72849d4fcee7 ("usb: typec: ucsi: stm32g0: add support for stm32g0 controller") Signed-off-by: Fabrice Gasnier --- drivers/usb/typec/ucsi/ucsi_stm32g0.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/usb/typec/ucsi/ucsi_stm32g0.c b/drivers/usb/typec/ucsi/ucsi_stm32g0.c index 93d7806681cf..7d6576778dad 100644 --- a/drivers/usb/typec/ucsi/ucsi_stm32g0.c +++ b/drivers/usb/typec/ucsi/ucsi_stm32g0.c @@ -395,9 +395,13 @@ static int ucsi_stm32g0_sync_write(struct ucsi *ucsi, unsigned int offset, const size_t len) { struct ucsi_stm32g0 *g0 = ucsi_get_drvdata(ucsi); + bool ack = UCSI_COMMAND(*(u64 *)val) == UCSI_ACK_CC_CI; int ret; - set_bit(COMMAND_PENDING, &g0->flags); + if (ack) + set_bit(ACK_PENDING, &g0->flags); + else + set_bit(COMMAND_PENDING, &g0->flags); ret = ucsi_stm32g0_async_write(ucsi, offset, val, len); if (ret) @@ -405,9 +409,14 @@ static int ucsi_stm32g0_sync_write(struct ucsi *ucsi, unsigned int offset, const if (!wait_for_completion_timeout(&g0->complete, msecs_to_jiffies(5000))) ret = -ETIMEDOUT; + else + return 0; out_clear_bit: - clear_bit(COMMAND_PENDING, &g0->flags); + if (ack) + clear_bit(ACK_PENDING, &g0->flags); + else + clear_bit(COMMAND_PENDING, &g0->flags); return ret; } @@ -428,8 +437,9 @@ static irqreturn_t ucsi_stm32g0_irq_handler(int irq, void *data) if (UCSI_CCI_CONNECTOR(cci)) ucsi_connector_change(g0->ucsi, UCSI_CCI_CONNECTOR(cci)); - if (test_bit(COMMAND_PENDING, &g0->flags) && - cci & (UCSI_CCI_ACK_COMPLETE | UCSI_CCI_COMMAND_COMPLETE)) + if (cci & UCSI_CCI_ACK_COMPLETE && test_and_clear_bit(ACK_PENDING, &g0->flags)) + complete(&g0->complete); + if (cci & UCSI_CCI_COMMAND_COMPLETE && test_and_clear_bit(COMMAND_PENDING, &g0->flags)) complete(&g0->complete); return IRQ_HANDLED;