From nobody Thu Sep 18 23:14:45 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5FF65C43217 for ; Thu, 1 Dec 2022 13:49:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231633AbiLANtJ (ORCPT ); Thu, 1 Dec 2022 08:49:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33798 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229748AbiLANtD (ORCPT ); Thu, 1 Dec 2022 08:49:03 -0500 Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4C82E1DA5E for ; Thu, 1 Dec 2022 05:49:02 -0800 (PST) Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2B15l1vB016609; Thu, 1 Dec 2022 07:48:50 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=O24ewM62YnyTshopgCFYg5eq7HQMvKb/cYKJclNcynE=; b=iH+D/pvM3F2HsdV3sbPIDmZMdTQM3pFHKpJq7eZLee9i/u69NRVObv1KHnylpXDx7ZW/ a5L/fxVSe+Y+kfarQfLMGjWxx9iBQS5Ecn2cV7K56rtxnXRJW+gZVGMkupk/uhGNYsLa Y/uT/3a8xeao+GGcs2AcKo5xUUKE19Csjn+SE3s8JxYCLevaOqeqcuvATznVKDyhTfge Qdy3VYF+3Ww7kS5JxfbIjCZi2OZ1eALVSI9F8xk7xed3OoCyz9bmBKDEwvOCmMGoIlgK xci/82cGnKqQXRrPWNynyJLv6+A/ijbd9xAb3cyJs/3fKXH6VwlYbzKDDHf8H1i9Zves WQ== Received: from ediex01.ad.cirrus.com ([84.19.233.68]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 3m6k75rhqm-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 01 Dec 2022 07:48:50 -0600 Received: from ediex01.ad.cirrus.com (198.61.84.80) by ediex01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.20; Thu, 1 Dec 2022 07:48:46 -0600 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by ediex01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.2.1118.20 via Frontend Transport; Thu, 1 Dec 2022 07:48:46 -0600 Received: from edi-sw-dsktp-006.ad.cirrus.com (edi-sw-dsktp-006.ad.cirrus.com [198.90.251.111]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 0BCC4B38; Thu, 1 Dec 2022 13:48:46 +0000 (UTC) From: Richard Fitzgerald To: , CC: , , , , , Richard Fitzgerald Subject: [PATCH 3/3] soundwire: cadence: Drain the RX FIFO after an IO timeout Date: Thu, 1 Dec 2022 13:48:45 +0000 Message-ID: <20221201134845.4055907-4-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20221201134845.4055907-1-rf@opensource.cirrus.com> References: <20221201134845.4055907-1-rf@opensource.cirrus.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-ORIG-GUID: 0xpdTaddmfdlDdsnGRcbsX2iSErxeRUZ X-Proofpoint-GUID: 0xpdTaddmfdlDdsnGRcbsX2iSErxeRUZ X-Proofpoint-Spam-Reason: safe Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" If wait_for_completion_timeout() times-out in _cdns_xfer_msg() it is possible that something could have been written to the RX FIFO. In this case, we should drain the RX FIFO so that anything in it doesn't carry over and mess up the next transfer. Obviously, if we got to this state something went wrong, and we don't really know the state of everything. The cleanup in this situation cannot be bullet-proof but we should attempt to avoid breaking future transaction, if only to reduce the amount of error noise when debugging the failure from a kernel log. Note that this patch only implements the draining for blocking (non-deferred) transfers. The deferred API doesn't have any proper handling of error conditions and would need some re-design before implementing cleanup. That is a task for a separate patch... Signed-off-by: Richard Fitzgerald Reviewed-by: Pierre-Louis Bossart --- drivers/soundwire/cadence_master.c | 48 ++++++++++++++++-------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence= _master.c index 95c84d9f0775..6bffecf3d61a 100644 --- a/drivers/soundwire/cadence_master.c +++ b/drivers/soundwire/cadence_master.c @@ -555,6 +555,28 @@ cdns_fill_msg_resp(struct sdw_cdns *cdns, return SDW_CMD_OK; } =20 +static void cdns_read_response(struct sdw_cdns *cdns) +{ + u32 num_resp, cmd_base; + int i; + + BUILD_BUG_ON(ARRAY_SIZE(cdns->response_buf) < CDNS_MCP_CMD_LEN); + + num_resp =3D cdns_readl(cdns, CDNS_MCP_FIFOSTAT); + num_resp &=3D CDNS_MCP_RX_FIFO_AVAIL; + if (num_resp > ARRAY_SIZE(cdns->response_buf)) { + dev_warn(cdns->dev, "RX AVAIL %d too long\n", num_resp); + num_resp =3D CDNS_MCP_CMD_LEN; + } + + cmd_base =3D CDNS_MCP_CMD_BASE; + + for (i =3D 0; i < num_resp; i++) { + cdns->response_buf[i] =3D cdns_readl(cdns, cmd_base); + cmd_base +=3D CDNS_MCP_CMD_WORD_LEN; + } +} + static enum sdw_command_response _cdns_xfer_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int cmd, int offset, int count, bool defer) @@ -596,6 +618,10 @@ _cdns_xfer_msg(struct sdw_cdns *cdns, struct sdw_msg *= msg, int cmd, dev_err(cdns->dev, "IO transfer timed out, cmd %d device %d addr %x len = %d\n", cmd, msg->dev_num, msg->addr, msg->len); msg->len =3D 0; + + /* Drain anything in the RX_FIFO */ + cdns_read_response(cdns); + return SDW_CMD_TIMEOUT; } =20 @@ -769,28 +795,6 @@ EXPORT_SYMBOL(cdns_read_ping_status); * IRQ handling */ =20 -static void cdns_read_response(struct sdw_cdns *cdns) -{ - u32 num_resp, cmd_base; - int i; - - BUILD_BUG_ON(ARRAY_SIZE(cdns->response_buf) < CDNS_MCP_CMD_LEN); - - num_resp =3D cdns_readl(cdns, CDNS_MCP_FIFOSTAT); - num_resp &=3D CDNS_MCP_RX_FIFO_AVAIL; - if (num_resp > ARRAY_SIZE(cdns->response_buf)) { - dev_warn(cdns->dev, "RX AVAIL %d too long\n", num_resp); - num_resp =3D CDNS_MCP_CMD_LEN; - } - - cmd_base =3D CDNS_MCP_CMD_BASE; - - for (i =3D 0; i < num_resp; i++) { - cdns->response_buf[i] =3D cdns_readl(cdns, cmd_base); - cmd_base +=3D CDNS_MCP_CMD_WORD_LEN; - } -} - static int cdns_update_slave_status(struct sdw_cdns *cdns, u64 slave_intstat) { --=20 2.30.2