From patchwork Thu Jun 27 14:44:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13714505 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 CB1ABC3064D for ; Thu, 27 Jun 2024 14:45:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References :Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=gWQEDBR2cvKHd61KPN3Oc0zu2avyS++NhmAlrTQ8dMU=; b=ruh2PjUvxS4mQrP5rf/rJYD4aC lKfO4a3XuTVPwtpLihJ9FEz5n8LVbCXyx/vwnkeB8Ke+o9ZqZ/S5EwHK7PLEOUEiKM3ZZ2B3w3lFR dLHuaZ0nFuwnZHvnBVMJsViLemVexIo8DDwXepLL/kbMWrsoidNB4xBHmc8bGB6G636h6uOzmTfuy peXuDmTHk+axwNwyzhRD4GambGSP6dmN60GJraQ84Gtw5+/RfUTQPnmktj3bn7ZW+GUCtS9ymR3WF fI64faPeDT6Y3XLYzaWSNfEWcRObzcVUTFQ6fce0Gyr7hskFKlUljjIJNBD5xhDYYGCtKOyig0CqY dTRLe0FA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sMqN2-0000000AgSR-0zWV; Thu, 27 Jun 2024 14:45:08 +0000 Received: from mail-lj1-x22a.google.com ([2a00:1450:4864:20::22a]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sMqMn-0000000AgLi-2qHn for linux-arm-kernel@lists.infradead.org; Thu, 27 Jun 2024 14:44:56 +0000 Received: by mail-lj1-x22a.google.com with SMTP id 38308e7fff4ca-2eaafda3b5cso81727291fa.3 for ; Thu, 27 Jun 2024 07:44:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1719499484; x=1720104284; darn=lists.infradead.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=gWQEDBR2cvKHd61KPN3Oc0zu2avyS++NhmAlrTQ8dMU=; b=qWLhM0HA+4Zx49Z+1riWWJkE0GevNydYg8MwwiBRsEHJev0VzELtdzJPPLsRzsJt3c npBBdOhnZUd1ZcWNQ4HqEDnRcWWRPkJ0uq2Sv3oPqy5yYoYiOaxI6jS/xFLsHJDC6wYG oqJ/FeFLQDfHISGshB1lE78nnitVrgo8hIq0E2BWG7EhS/RLaD4SxiBtgmmdwkgxonXm HSfAEuiHICn+4zgQ97p6BL5RVmb0lRqaKFIhP5WVgD3k2wh6HwRY9tzIhBgMQ5AR6fus kcPcDZ+2xjX8sgYfz7IXl4BYRvSnRAxJ6r0VYJUNBiU7CbGkkzfiZbYBkdFUKqUlMgeS 5TGA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719499484; x=1720104284; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=gWQEDBR2cvKHd61KPN3Oc0zu2avyS++NhmAlrTQ8dMU=; b=ubFQdzEWc6TtXts38HB+X7Pnfgtkx/xbDf+xHVXyAKadyM6D8jEPWhmsYxLaPgYdJb vCQb13o4/9gsPEliu6Y5StlYQlEpwIIf4a+IFtByKjpTsKS2kNiHgPJT32uR89WFMqtb vw+1ppr/u6RBSdU/TEC+5c8eeVmD+AEDeQ2K71jl6A2tGcow4RYs/RzrtmNU2Ix4dcrD 2Tib3qedTJu+NH+dClYXe5nyVyYClRIrfc4jJJdqKMVUgA8vcUAw4YqMBNStH49ea/qk xGQkm/Gy1v2xj+MOOrWnDjTJNEZDGdhtqlWtFMw6CfjmNKOqqRWb2qxrSBotMwdo58Di tf2A== X-Forwarded-Encrypted: i=1; AJvYcCXEHjgA1hhTelgkdVydr7MFDIRG7zsQj/yfsL4EBZh862IQkrJszmYYCvCZe2Z4wY0wyMOHuo07kIxS2MDQqMpaoxsFGF/N0HV4kIUdxBwb2hkdV1c= X-Gm-Message-State: AOJu0YxdPyXBkP3rMxMUMabfIKNdpEwXvm/5pDoO9DxTHNym1MbNp7ws DMCRnw6HjjrUM/oAKL/cQrTXN9pJ2gRIfaiTeLG8UUxPfzK6hhBcTEwdkznQ/YE= X-Google-Smtp-Source: AGHT+IF8lRY4yxVYxkR4RRTjf0SHogAEtg76W/F0NnLyvHUeyA8JM9QhKMO2Pbyo9TObJ219yDtmqA== X-Received: by 2002:a2e:9d81:0:b0:2ec:57ff:92c7 with SMTP id 38308e7fff4ca-2ec593d8613mr85645941fa.14.1719499483920; Thu, 27 Jun 2024 07:44:43 -0700 (PDT) Received: from umbar.lan ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-2ee4a34447fsm2775911fa.11.2024.06.27.07.44.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Jun 2024 07:44:43 -0700 (PDT) From: Dmitry Baryshkov Date: Thu, 27 Jun 2024 17:44:40 +0300 Subject: [PATCH v4 1/7] usb: typec: ucsi: move ucsi_acknowledge() from ucsi_read_error() MIME-Version: 1.0 Message-Id: <20240627-ucsi-rework-interface-v4-1-289ddc6874c7@linaro.org> References: <20240627-ucsi-rework-interface-v4-0-289ddc6874c7@linaro.org> In-Reply-To: <20240627-ucsi-rework-interface-v4-0-289ddc6874c7@linaro.org> To: Heikki Krogerus , Greg Kroah-Hartman , Maxime Coquelin , Alexandre Torgue Cc: Nikita Travkin , Neil Armstrong , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1498; i=dmitry.baryshkov@linaro.org; h=from:subject:message-id; bh=RCY/4C0+GrYFBzSYId6jLzfsNK5WXotKJnVh4nnnjG0=; b=owEBbQGS/pANAwAKAYs8ij4CKSjVAcsmYgBmfXrZ1Gmvzxm4i0ZRKQCtxunw01G50Fjio700n 1wqd1wu/bqJATMEAAEKAB0WIQRMcISVXLJjVvC4lX+LPIo+Aiko1QUCZn162QAKCRCLPIo+Aiko 1eSUB/0RSAnq/bhc3trWD1uYPal7bW48CKzEDX0qEHMDzyjk1GJlHlUnP0d00i2vy8nmi4Y1sGn JAiSOJ/lwWBwJjTPJX+SM9WsqCMpMe+OhNP0pqyWhqupbTGR/xgmDHGDJN2LlgU/i9TwEYv+syQ JtwlhKuXilFvwSmQC0JHXxvdRzCHZ6YbtmckLEsqLLKsM8LmjI52G/ak/FSYcgemaKyXQs/iinQ bGgfFtTdVreI1ds55pjr1dCQ02q4k0RWJlgpVVqNAa43/P04n3jC5shcezrTu99ROP34Y0ORwxe +6Z9pQxIEgaq8/bd0vT5Eeas2kReYuVdzwWPirdh2qdhBySr X-Developer-Key: i=dmitry.baryshkov@linaro.org; a=openpgp; fpr=8F88381DD5C873E4AE487DA5199BF1243632046A X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240627_074453_825381_671CDF1A X-CRM114-Status: GOOD ( 11.48 ) 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 As a preparation for reworking UCSI command handling, move ucsi_acknowledge() for the failed command from ucsi_read_error() to ucsi_exec_command(). Tested-by: Heikki Krogerus Reviewed-by: Heikki Krogerus Signed-off-by: Dmitry Baryshkov --- drivers/usb/typec/ucsi/ucsi.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c index 59eaa49042f4..651c22473472 100644 --- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -71,11 +71,6 @@ static int ucsi_read_error(struct ucsi *ucsi, u8 connector_num) u16 error; int ret; - /* Acknowledge the command that failed */ - ret = ucsi_acknowledge(ucsi, false); - if (ret) - return ret; - command = UCSI_GET_ERROR_STATUS | UCSI_CONNECTOR_NUMBER(connector_num); ret = ucsi_exec_command(ucsi, command); if (ret < 0) @@ -182,13 +177,14 @@ static int ucsi_exec_command(struct ucsi *ucsi, u64 cmd) } if (cci & UCSI_CCI_ERROR) { - if (cmd == UCSI_GET_ERROR_STATUS) { - ret = ucsi_acknowledge(ucsi, false); - if (ret) - return ret; + /* Acknowledge the command that failed */ + ret = ucsi_acknowledge(ucsi, false); + if (ret) + return ret; + if (cmd == UCSI_GET_ERROR_STATUS) return -EIO; - } + return ucsi_read_error(ucsi, connector_num); } From patchwork Thu Jun 27 14:44:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13714508 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 1B508C2BD09 for ; Thu, 27 Jun 2024 14:45:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References :Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=9xc5CJzlZcckit69hsy7iMWkzWV2hcPjFjQs+d5LaDk=; b=K8Zo6TT1d3yGJaD23r5qNxppSi Ptqz9Fcnn90KXj/05zZtqCWtXhn9JFJdOXllouYSkt+K+NzXzONAPn4PRadiSBRSFWAxMcr15V36R +JSxkHSV6sD0SmrLla72ab0asjFd2jQHFLjZU98XA589mvTziVknCKdnCfKCW4WKy7jSZt0+9jCRa AoI6q6DZc7y0Fje7iGxHgIh1pmKlXoYhMj3kPiiesaYpE1uJVl3QZaP1R6o/v+ckEfOH3pBZewZVS bv0D1H+CY4NHFOyfJ/FFq69DDqyruWoWmJY0W2RUPuAVF+sB6XgX5wB4cEUe3eAgWG5HMGL5kxcVL fExnnqLw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sMqNE-0000000AgX6-074L; Thu, 27 Jun 2024 14:45:20 +0000 Received: from mail-lj1-x235.google.com ([2a00:1450:4864:20::235]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sMqMo-0000000AgLp-2Tms for linux-arm-kernel@lists.infradead.org; Thu, 27 Jun 2024 14:44:57 +0000 Received: by mail-lj1-x235.google.com with SMTP id 38308e7fff4ca-2eabd22d3f4so96541161fa.1 for ; Thu, 27 Jun 2024 07:44:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1719499485; x=1720104285; darn=lists.infradead.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=9xc5CJzlZcckit69hsy7iMWkzWV2hcPjFjQs+d5LaDk=; b=zQIcJUWQu8PZ+c43pKELRq1TTqnn8sukjmXv5ykIqSOwib0s41KJGo3etrqi0DwaCi aas+WsBvv0ARZ0v4wVOf/nHKoRG6c9wT5Yb6ROCM5Gzp960E0OHNDrIU5vqHonRoFx2B yKcPImvE3FHKXHw7+bEayrB/mOB+T+NqoDMVfgB2xcqX5IAIJVa6QOLaAKs9yzKXthar jo3SxKIhb8LwTI9aHo71AZjdVjcXS6ebsp/G0bng3rHDF9Ilyy+Kkyg53IPNKjCirdQ6 SjuJHsxYpv7lg3FYtcFvg+8u5d7Sg2IKe+mnOGfjiZ5YK7zlVrUMBfvhEvmgscGoqHRA XThg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719499485; x=1720104285; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=9xc5CJzlZcckit69hsy7iMWkzWV2hcPjFjQs+d5LaDk=; b=iGeQq0HMwOob4jDyfrZVEGd5DDOZSvObTXMmRQC3dpeeJ0U3aKkgK7JQrW9oypsgEO /iRxZXkYdD2nj66mQpRqE9kROofHUFRiEBN5PXywto1rzwE6erQA63G/bW6BjrCG46hl bRzeXxPEHPN1xxKmNQXNPLunGD1vYsvdSn2L+p4oGtn/8s3YeEoDiN55Z/A6778EpuGF DWqpMtW+wOVychrYLcFhG96iT9lhfj3wIxiy+ukNVwDFr5U19usY1VLVgPVCwzG7B6f0 NPSGsSuWW5YOibYTNCXOUFUsv1RFwHOVHg5JOtrgYE+1EePVmxCpiTexz76Nkg4D7JLH tHDQ== X-Forwarded-Encrypted: i=1; AJvYcCUIHDFAqpTSTIupcZ1L69UWlKb9p0ZRpCdvDzTZkU1QwQDwkFlaqDMyFTEzKVmGFtQpOWVvNSGbHhMcjUxPqkducO8UPcLBA2kziUA5Id925tnbaoE= X-Gm-Message-State: AOJu0Yzvq165mAmWB0kYLxpZFijxtvQj4XbNH677yPtsipdg6bga4x/X 9Q+RIufc8WZeY7mXuV5XvqYy/SEsTceMiPO7ilLdoD6QuwY1e/dZPFnBP0kQAc4= X-Google-Smtp-Source: AGHT+IGRBJggbLJLBGfYgW/0wPx8tCJWmx0m9/7rc4DkPfbVNa85+lHHNi7nRNQtuOIb9Hu1/GYCkw== X-Received: by 2002:a2e:9ed5:0:b0:2ec:50fa:1e47 with SMTP id 38308e7fff4ca-2ec5b2a0a1fmr87677291fa.21.1719499485331; Thu, 27 Jun 2024 07:44:45 -0700 (PDT) Received: from umbar.lan ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-2ee4a34447fsm2775911fa.11.2024.06.27.07.44.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Jun 2024 07:44:44 -0700 (PDT) From: Dmitry Baryshkov Date: Thu, 27 Jun 2024 17:44:41 +0300 Subject: [PATCH v4 2/7] usb: typec: ucsi: simplify command sending API MIME-Version: 1.0 Message-Id: <20240627-ucsi-rework-interface-v4-2-289ddc6874c7@linaro.org> References: <20240627-ucsi-rework-interface-v4-0-289ddc6874c7@linaro.org> In-Reply-To: <20240627-ucsi-rework-interface-v4-0-289ddc6874c7@linaro.org> To: Heikki Krogerus , Greg Kroah-Hartman , Maxime Coquelin , Alexandre Torgue Cc: Nikita Travkin , Neil Armstrong , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=17396; i=dmitry.baryshkov@linaro.org; h=from:subject:message-id; bh=7MwctdmVB+iJTzrgBECktp6juS2YdFsvbJpqsYqcihg=; b=owEBbQGS/pANAwAKAYs8ij4CKSjVAcsmYgBmfXrZ0OcrotJEk0yj9kOgl26Bg9OPYxvJb51oC vKo9XBk7kaJATMEAAEKAB0WIQRMcISVXLJjVvC4lX+LPIo+Aiko1QUCZn162QAKCRCLPIo+Aiko 1ZAYB/94Sb2MnkUMGHom+70CRNc+DdhObAAyvHadRA1MAzWCCA4W8cZ21XqtktpZmvG0xvAhbGi iyMSgOYdpq9oqBnMQbUumxNWu8wP73KleiYUhWH0QEMpNraDuVF+ZrQi3dCdvTtmtjq7smmNdn7 Xyt15+sfDIkgYURcfmRxKnAsJYZ2rb8b89BGTLLpFdzxhoTRRocOF7C/6D4McJrJ/E1oLyVl6qW F2r+J3l1/sJrcFmUWXh8fumHzLQz0AiuaGcJYSpq3nGqGFRbbr0JIUPx9EmvWkXfimUQqNPSuu6 oaVhLzlkx8jDhvVwuvkqp9nvAljgbMTA8Ip3pI2Fr2D6wtdz X-Developer-Key: i=dmitry.baryshkov@linaro.org; a=openpgp; fpr=8F88381DD5C873E4AE487DA5199BF1243632046A X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240627_074454_683362_BDDF6501 X-CRM114-Status: GOOD ( 16.46 ) 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 The sync_write and async_write are used only for writing UCSI commands to the UCSI_CONTROL offsets. Rename sync_write and async_write operations to sync_control and async_control accordingly. Drop the offset and length fields and pass u64 command instead. Tested-by: Heikki Krogerus Reviewed-by: Heikki Krogerus Signed-off-by: Dmitry Baryshkov --- drivers/usb/typec/ucsi/ucsi.c | 18 +++++++---------- drivers/usb/typec/ucsi/ucsi.h | 10 ++++------ drivers/usb/typec/ucsi/ucsi_acpi.c | 31 ++++++++++++++---------------- drivers/usb/typec/ucsi/ucsi_ccg.c | 34 +++++++++++++++------------------ drivers/usb/typec/ucsi/ucsi_glink.c | 14 ++++++-------- drivers/usb/typec/ucsi/ucsi_stm32g0.c | 24 +++++++++++------------ drivers/usb/typec/ucsi/ucsi_yoga_c630.c | 20 +++++++------------ 7 files changed, 64 insertions(+), 87 deletions(-) diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c index 651c22473472..e8172b7711c8 100644 --- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -60,7 +60,7 @@ static int ucsi_acknowledge(struct ucsi *ucsi, bool conn_ack) ctrl |= UCSI_ACK_CONNECTOR_CHANGE; } - return ucsi->ops->sync_write(ucsi, UCSI_CONTROL, &ctrl, sizeof(ctrl)); + return ucsi->ops->sync_control(ucsi, ctrl); } static int ucsi_exec_command(struct ucsi *ucsi, u64 command); @@ -155,7 +155,7 @@ static int ucsi_exec_command(struct ucsi *ucsi, u64 cmd) connector_num = 0; } - ret = ucsi->ops->sync_write(ucsi, UCSI_CONTROL, &cmd, sizeof(cmd)); + ret = ucsi->ops->sync_control(ucsi, cmd); if (ret) return ret; @@ -1350,8 +1350,7 @@ static int ucsi_reset_ppm(struct ucsi *ucsi) */ if (cci & UCSI_CCI_RESET_COMPLETE) { command = UCSI_SET_NOTIFICATION_ENABLE; - ret = ucsi->ops->async_write(ucsi, UCSI_CONTROL, &command, - sizeof(command)); + ret = ucsi->ops->async_control(ucsi, command); if (ret < 0) goto out; @@ -1372,8 +1371,7 @@ static int ucsi_reset_ppm(struct ucsi *ucsi) } command = UCSI_PPM_RESET; - ret = ucsi->ops->async_write(ucsi, UCSI_CONTROL, &command, - sizeof(command)); + ret = ucsi->ops->async_control(ucsi, command); if (ret < 0) goto out; @@ -1394,9 +1392,7 @@ static int ucsi_reset_ppm(struct ucsi *ucsi) /* If the PPM is still doing something else, reset it again. */ if (cci & ~UCSI_CCI_RESET_COMPLETE) { - ret = ucsi->ops->async_write(ucsi, UCSI_CONTROL, - &command, - sizeof(command)); + ret = ucsi->ops->async_control(ucsi, command); if (ret < 0) goto out; } @@ -1924,7 +1920,7 @@ struct ucsi *ucsi_create(struct device *dev, const struct ucsi_operations *ops) { struct ucsi *ucsi; - if (!ops || !ops->read || !ops->sync_write || !ops->async_write) + if (!ops || !ops->read || !ops->sync_control || !ops->async_control) return ERR_PTR(-EINVAL); ucsi = kzalloc(sizeof(*ucsi), GFP_KERNEL); @@ -2000,7 +1996,7 @@ void ucsi_unregister(struct ucsi *ucsi) cancel_work_sync(&ucsi->resume_work); /* Disable notifications */ - ucsi->ops->async_write(ucsi, UCSI_CONTROL, &cmd, sizeof(cmd)); + ucsi->ops->async_control(ucsi, cmd); if (!ucsi->connector) return; diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h index fe95a80050d3..a8c161a39f11 100644 --- a/drivers/usb/typec/ucsi/ucsi.h +++ b/drivers/usb/typec/ucsi/ucsi.h @@ -57,8 +57,8 @@ struct dentry; /** * struct ucsi_operations - UCSI I/O operations * @read: Read operation - * @sync_write: Blocking write operation - * @async_write: Non-blocking write operation + * @sync_control: Blocking control operation + * @async_control: Non-blocking control operation * @update_altmodes: Squashes duplicate DP altmodes * @update_connector: Update connector capabilities before registering * @connector_status: Updates connector status, called holding connector lock @@ -70,10 +70,8 @@ struct dentry; struct ucsi_operations { int (*read)(struct ucsi *ucsi, unsigned int offset, void *val, size_t val_len); - int (*sync_write)(struct ucsi *ucsi, unsigned int offset, - const void *val, size_t val_len); - int (*async_write)(struct ucsi *ucsi, unsigned int offset, - const void *val, size_t val_len); + int (*sync_control)(struct ucsi *ucsi, u64 command); + int (*async_control)(struct ucsi *ucsi, u64 command); bool (*update_altmodes)(struct ucsi *ucsi, struct ucsi_altmode *orig, struct ucsi_altmode *updated); void (*update_connector)(struct ucsi_connector *con); diff --git a/drivers/usb/typec/ucsi/ucsi_acpi.c b/drivers/usb/typec/ucsi/ucsi_acpi.c index adf32ca0f761..f54e4722d8f6 100644 --- a/drivers/usb/typec/ucsi/ucsi_acpi.c +++ b/drivers/usb/typec/ucsi/ucsi_acpi.c @@ -61,22 +61,20 @@ static int ucsi_acpi_read(struct ucsi *ucsi, unsigned int offset, return 0; } -static int ucsi_acpi_async_write(struct ucsi *ucsi, unsigned int offset, - const void *val, size_t val_len) +static int ucsi_acpi_async_control(struct ucsi *ucsi, u64 command) { struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); - memcpy(ua->base + offset, val, val_len); - ua->cmd = *(u64 *)val; + memcpy(ua->base + UCSI_CONTROL, &command, sizeof(command)); + ua->cmd = command; return ucsi_acpi_dsm(ua, UCSI_DSM_FUNC_WRITE); } -static int ucsi_acpi_sync_write(struct ucsi *ucsi, unsigned int offset, - const void *val, size_t val_len) +static int ucsi_acpi_sync_control(struct ucsi *ucsi, u64 command) { struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); - bool ack = UCSI_COMMAND(*(u64 *)val) == UCSI_ACK_CC_CI; + bool ack = UCSI_COMMAND(command) == UCSI_ACK_CC_CI; int ret; if (ack) @@ -84,7 +82,7 @@ static int ucsi_acpi_sync_write(struct ucsi *ucsi, unsigned int offset, else set_bit(UCSI_ACPI_COMMAND_PENDING, &ua->flags); - ret = ucsi_acpi_async_write(ucsi, offset, val, val_len); + ret = ucsi_acpi_async_control(ucsi, command); if (ret) goto out_clear_bit; @@ -102,8 +100,8 @@ static int ucsi_acpi_sync_write(struct ucsi *ucsi, unsigned int offset, static const struct ucsi_operations ucsi_acpi_ops = { .read = ucsi_acpi_read, - .sync_write = ucsi_acpi_sync_write, - .async_write = ucsi_acpi_async_write + .sync_control = ucsi_acpi_sync_control, + .async_control = ucsi_acpi_async_control }; static int @@ -125,8 +123,8 @@ ucsi_zenbook_read(struct ucsi *ucsi, unsigned int offset, void *val, size_t val_ static const struct ucsi_operations ucsi_zenbook_ops = { .read = ucsi_zenbook_read, - .sync_write = ucsi_acpi_sync_write, - .async_write = ucsi_acpi_async_write + .sync_control = ucsi_acpi_sync_control, + .async_control = ucsi_acpi_async_control }; static int ucsi_gram_read(struct ucsi *ucsi, unsigned int offset, @@ -157,13 +155,12 @@ static int ucsi_gram_read(struct ucsi *ucsi, unsigned int offset, return ret; } -static int ucsi_gram_sync_write(struct ucsi *ucsi, unsigned int offset, - const void *val, size_t val_len) +static int ucsi_gram_sync_control(struct ucsi *ucsi, u64 command) { struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); int ret; - ret = ucsi_acpi_sync_write(ucsi, offset, val, val_len); + ret = ucsi_acpi_sync_control(ucsi, command); if (ret < 0) return ret; @@ -177,8 +174,8 @@ static int ucsi_gram_sync_write(struct ucsi *ucsi, unsigned int offset, static const struct ucsi_operations ucsi_gram_ops = { .read = ucsi_gram_read, - .sync_write = ucsi_gram_sync_write, - .async_write = ucsi_acpi_async_write + .sync_control = ucsi_gram_sync_control, + .async_control = ucsi_acpi_async_control }; static const struct dmi_system_id ucsi_acpi_quirks[] = { diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c index dda7c7c94e08..76b39bb9762d 100644 --- a/drivers/usb/typec/ucsi/ucsi_ccg.c +++ b/drivers/usb/typec/ucsi/ucsi_ccg.c @@ -610,25 +610,23 @@ static int ucsi_ccg_read(struct ucsi *ucsi, unsigned int offset, return ret; } -static int ucsi_ccg_async_write(struct ucsi *ucsi, unsigned int offset, - const void *val, size_t val_len) +static int ucsi_ccg_async_control(struct ucsi *ucsi, u64 command) { struct ucsi_ccg *uc = ucsi_get_drvdata(ucsi); - u16 reg = CCGX_RAB_UCSI_DATA_BLOCK(offset); + u16 reg = CCGX_RAB_UCSI_DATA_BLOCK(UCSI_CONTROL); /* - * UCSI may read CCI instantly after async_write, + * UCSI may read CCI instantly after async_control, * clear CCI to avoid caller getting wrong data before we get CCI from ISR */ spin_lock(&uc->op_lock); uc->op_data.cci = 0; spin_unlock(&uc->op_lock); - return ccg_write(uc, reg, val, val_len); + return ccg_write(uc, reg, (u8 *)&command, sizeof(command)); } -static int ucsi_ccg_sync_write(struct ucsi *ucsi, unsigned int offset, - const void *val, size_t val_len) +static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command) { struct ucsi_ccg *uc = ucsi_get_drvdata(ucsi); struct ucsi_connector *con; @@ -639,19 +637,17 @@ static int ucsi_ccg_sync_write(struct ucsi *ucsi, unsigned int offset, pm_runtime_get_sync(uc->dev); set_bit(DEV_CMD_PENDING, &uc->flags); - if (offset == UCSI_CONTROL && val_len == sizeof(uc->last_cmd_sent)) { - uc->last_cmd_sent = *(u64 *)val; + uc->last_cmd_sent = command; - if (UCSI_COMMAND(uc->last_cmd_sent) == UCSI_SET_NEW_CAM && - uc->has_multiple_dp) { - con_index = (uc->last_cmd_sent >> 16) & - UCSI_CMD_CONNECTOR_MASK; - con = &uc->ucsi->connector[con_index - 1]; - ucsi_ccg_update_set_new_cam_cmd(uc, con, (u64 *)val); - } + if (UCSI_COMMAND(uc->last_cmd_sent) == UCSI_SET_NEW_CAM && + uc->has_multiple_dp) { + con_index = (uc->last_cmd_sent >> 16) & + UCSI_CMD_CONNECTOR_MASK; + con = &uc->ucsi->connector[con_index - 1]; + ucsi_ccg_update_set_new_cam_cmd(uc, con, &command); } - ret = ucsi_ccg_async_write(ucsi, offset, val, val_len); + ret = ucsi_ccg_async_control(ucsi, command); if (ret) goto err_clear_bit; @@ -668,8 +664,8 @@ static int ucsi_ccg_sync_write(struct ucsi *ucsi, unsigned int offset, static const struct ucsi_operations ucsi_ccg_ops = { .read = ucsi_ccg_read, - .sync_write = ucsi_ccg_sync_write, - .async_write = ucsi_ccg_async_write, + .sync_control = ucsi_ccg_sync_control, + .async_control = ucsi_ccg_async_control, .update_altmodes = ucsi_ccg_update_altmodes }; diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c index 2fa973afe4e6..ebd76257c4fc 100644 --- a/drivers/usb/typec/ucsi/ucsi_glink.c +++ b/drivers/usb/typec/ucsi/ucsi_glink.c @@ -143,21 +143,19 @@ static int pmic_glink_ucsi_locked_write(struct pmic_glink_ucsi *ucsi, unsigned i return 0; } -static int pmic_glink_ucsi_async_write(struct ucsi *__ucsi, unsigned int offset, - const void *val, size_t val_len) +static int pmic_glink_ucsi_async_control(struct ucsi *__ucsi, u64 command) { struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(__ucsi); int ret; mutex_lock(&ucsi->lock); - ret = pmic_glink_ucsi_locked_write(ucsi, offset, val, val_len); + ret = pmic_glink_ucsi_locked_write(ucsi, UCSI_CONTROL, &command, sizeof(command)); mutex_unlock(&ucsi->lock); return ret; } -static int pmic_glink_ucsi_sync_write(struct ucsi *__ucsi, unsigned int offset, - const void *val, size_t val_len) +static int pmic_glink_ucsi_sync_control(struct ucsi *__ucsi, u64 command) { struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(__ucsi); unsigned long left; @@ -169,7 +167,7 @@ static int pmic_glink_ucsi_sync_write(struct ucsi *__ucsi, unsigned int offset, ucsi->sync_val = 0; reinit_completion(&ucsi->sync_ack); ucsi->sync_pending = true; - ret = pmic_glink_ucsi_locked_write(ucsi, offset, val, val_len); + ret = pmic_glink_ucsi_locked_write(ucsi, UCSI_CONTROL, &command, sizeof(command)); mutex_unlock(&ucsi->lock); left = wait_for_completion_timeout(&ucsi->sync_ack, 5 * HZ); @@ -217,8 +215,8 @@ static void pmic_glink_ucsi_connector_status(struct ucsi_connector *con) static const struct ucsi_operations pmic_glink_ucsi_ops = { .read = pmic_glink_ucsi_read, - .sync_write = pmic_glink_ucsi_sync_write, - .async_write = pmic_glink_ucsi_async_write, + .sync_control = pmic_glink_ucsi_sync_control, + .async_control = pmic_glink_ucsi_async_control, .update_connector = pmic_glink_ucsi_update_connector, .connector_status = pmic_glink_ucsi_connector_status, }; diff --git a/drivers/usb/typec/ucsi/ucsi_stm32g0.c b/drivers/usb/typec/ucsi/ucsi_stm32g0.c index ac69288e8bb0..396e2090e7c3 100644 --- a/drivers/usb/typec/ucsi/ucsi_stm32g0.c +++ b/drivers/usb/typec/ucsi/ucsi_stm32g0.c @@ -359,8 +359,7 @@ static int ucsi_stm32g0_read(struct ucsi *ucsi, unsigned int offset, void *val, return 0; } -static int ucsi_stm32g0_async_write(struct ucsi *ucsi, unsigned int offset, const void *val, - size_t len) +static int ucsi_stm32g0_async_control(struct ucsi *ucsi, u64 command) { struct ucsi_stm32g0 *g0 = ucsi_get_drvdata(ucsi); struct i2c_client *client = g0->client; @@ -373,19 +372,19 @@ static int ucsi_stm32g0_async_write(struct ucsi *ucsi, unsigned int offset, cons unsigned char *buf; int ret; - buf = kmalloc(len + 1, GFP_KERNEL); + buf = kmalloc(sizeof(command) + 1, GFP_KERNEL); if (!buf) return -ENOMEM; - buf[0] = offset; - memcpy(&buf[1], val, len); - msg[0].len = len + 1; + buf[0] = UCSI_CONTROL; + memcpy(&buf[1], &command, sizeof(command)); + msg[0].len = sizeof(command) + 1; msg[0].buf = buf; ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); kfree(buf); if (ret != ARRAY_SIZE(msg)) { - dev_err(g0->dev, "i2c write %02x, %02x error: %d\n", client->addr, offset, ret); + dev_err(g0->dev, "i2c write %02x, %02x error: %d\n", client->addr, UCSI_CONTROL, ret); return ret < 0 ? ret : -EIO; } @@ -393,11 +392,10 @@ static int ucsi_stm32g0_async_write(struct ucsi *ucsi, unsigned int offset, cons return 0; } -static int ucsi_stm32g0_sync_write(struct ucsi *ucsi, unsigned int offset, const void *val, - size_t len) +static int ucsi_stm32g0_sync_control(struct ucsi *ucsi, u64 command) { struct ucsi_stm32g0 *g0 = ucsi_get_drvdata(ucsi); - bool ack = UCSI_COMMAND(*(u64 *)val) == UCSI_ACK_CC_CI; + bool ack = UCSI_COMMAND(command) == UCSI_ACK_CC_CI; int ret; if (ack) @@ -405,7 +403,7 @@ static int ucsi_stm32g0_sync_write(struct ucsi *ucsi, unsigned int offset, const else set_bit(COMMAND_PENDING, &g0->flags); - ret = ucsi_stm32g0_async_write(ucsi, offset, val, len); + ret = ucsi_stm32g0_async_control(ucsi, command); if (ret) goto out_clear_bit; @@ -449,8 +447,8 @@ static irqreturn_t ucsi_stm32g0_irq_handler(int irq, void *data) static const struct ucsi_operations ucsi_stm32g0_ops = { .read = ucsi_stm32g0_read, - .sync_write = ucsi_stm32g0_sync_write, - .async_write = ucsi_stm32g0_async_write, + .sync_control = ucsi_stm32g0_sync_control, + .async_control = ucsi_stm32g0_async_control, }; static int ucsi_stm32g0_register(struct ucsi *ucsi) diff --git a/drivers/usb/typec/ucsi/ucsi_yoga_c630.c b/drivers/usb/typec/ucsi/ucsi_yoga_c630.c index 8bee0b469041..e5e8ba0c0eaa 100644 --- a/drivers/usb/typec/ucsi/ucsi_yoga_c630.c +++ b/drivers/usb/typec/ucsi/ucsi_yoga_c630.c @@ -56,23 +56,17 @@ static int yoga_c630_ucsi_read(struct ucsi *ucsi, unsigned int offset, } } -static int yoga_c630_ucsi_async_write(struct ucsi *ucsi, unsigned int offset, - const void *val, size_t val_len) +static int yoga_c630_ucsi_async_control(struct ucsi *ucsi, u64 command) { struct yoga_c630_ucsi *uec = ucsi_get_drvdata(ucsi); - if (offset != UCSI_CONTROL || - val_len != YOGA_C630_UCSI_WRITE_SIZE) - return -EINVAL; - - return yoga_c630_ec_ucsi_write(uec->ec, val); + return yoga_c630_ec_ucsi_write(uec->ec, (u8*)&command); } -static int yoga_c630_ucsi_sync_write(struct ucsi *ucsi, unsigned int offset, - const void *val, size_t val_len) +static int yoga_c630_ucsi_sync_control(struct ucsi *ucsi, u64 command) { struct yoga_c630_ucsi *uec = ucsi_get_drvdata(ucsi); - bool ack = UCSI_COMMAND(*(u64 *)val) == UCSI_ACK_CC_CI; + bool ack = UCSI_COMMAND(command) == UCSI_ACK_CC_CI; int ret; if (ack) @@ -82,7 +76,7 @@ static int yoga_c630_ucsi_sync_write(struct ucsi *ucsi, unsigned int offset, reinit_completion(&uec->complete); - ret = yoga_c630_ucsi_async_write(ucsi, offset, val, val_len); + ret = yoga_c630_ucsi_async_control(ucsi, command); if (ret) goto out_clear_bit; @@ -100,8 +94,8 @@ static int yoga_c630_ucsi_sync_write(struct ucsi *ucsi, unsigned int offset, const struct ucsi_operations yoga_c630_ucsi_ops = { .read = yoga_c630_ucsi_read, - .sync_write = yoga_c630_ucsi_sync_write, - .async_write = yoga_c630_ucsi_async_write, + .sync_control = yoga_c630_ucsi_sync_control, + .async_control = yoga_c630_ucsi_async_control, }; static void yoga_c630_ucsi_notify_ucsi(struct yoga_c630_ucsi *uec, u32 cci) From patchwork Thu Jun 27 14:44:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13714509 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 67CB2C2BD09 for ; Thu, 27 Jun 2024 14:45:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References :Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=UghCq0if0rPxKzwOGOdd2hJL8Uwk9IwhUB+0hzFweFk=; b=XDuXJznuKJxn2lUYN67h1D3dD9 dJ3K0qyIQ8Q8b6qMIsZjNhcLvwDDpEqNqcLWAUhIDNPVZru3gQLgsKXI92YNnYInTzBPbqlpLCD32 KE83OhckvQ8Ni6B/PNuFF0jZQ+ltv+iQdlQJLYA/ZnFFypvBPyQLGbMwXyWhR/VgB+5n0EyE+6TDn mKInPL7Pz3ImZtKG0yAk4Lh+gG7bHAqTTHo1Ebd/wlwZt/WdVESj/Lgb1xtRW8KIoRt2zm3KI+7SI ZC/tb9ZCapKesLsyaSweXBFxPT+2W9kYZ6MDsHGKWuW+a1fY0Wo13mecdrg/3wHH3Y0KqXv3PLMXw oveWpERg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sMqNK-0000000AgaW-09mN; Thu, 27 Jun 2024 14:45:26 +0000 Received: from mail-lj1-x231.google.com ([2a00:1450:4864:20::231]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sMqMn-0000000AgLq-2q3m for linux-arm-kernel@lists.infradead.org; Thu, 27 Jun 2024 14:44:58 +0000 Received: by mail-lj1-x231.google.com with SMTP id 38308e7fff4ca-2ec3f875e68so88786211fa.0 for ; Thu, 27 Jun 2024 07:44:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1719499486; x=1720104286; darn=lists.infradead.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=UghCq0if0rPxKzwOGOdd2hJL8Uwk9IwhUB+0hzFweFk=; b=Qe5m58O8jjaHPuZMiPNV5WZiieBRN3kQfhQ/XstgvcKLsJj4I/1m1qQvrZnIlwaZ9c l82s1jV5rqzbjyvf0nRTuIPBAyGxODuM7m9A1hf4GdKhJexNLpzBLL6TRcsOS4B7MYij 0tuueVA4NDC/ntgDguUlboawqPkE3sgDKcAu/8A+Ms3Xe83Q+RgC+vpgOlDmJh1c6VMG qg2Fc2nTasxTfsKkIQCEutQsUlvPRX1qdVEb0pK2uCAgTwdXTzIk4rpr3MkuHyY5RGES zXlXZom52nVDRjpbxsO6gH7GvpH1WhUepW6ZcalMqirrze8VvMS6+X90ruH3uaXKKvUZ Cg1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719499486; x=1720104286; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=UghCq0if0rPxKzwOGOdd2hJL8Uwk9IwhUB+0hzFweFk=; b=Cb66tVLVhPC7K3EDNiDNUfgcVEQvqjluUAFxQmZbS2br4uHW738ikqs80a+ohzk8nj a1AZ5M6wUfP1gSpPRxUF4+jJCDNhBEat3KqDjKp8oibZz+9LvJK7EbIhUwLYTVsLD3lq iqWqOu8vmGKu9Zucu03psMZjR9I1CuKAnEGUnOF4h4v7NC9iq2UYf2JaZ7TaqjfyJyNL 7YffGCUCVJNd8J7yoOFbK0YPeM45jQebavLCMId4d/UbhKx59rcsE+gfFo1HR8Ffq8iE wtyGC3BvrZbuUIiOx3gKkqw8ySQUUCUBLucU7IN6UcwK8j5OCZbpa5TeLd0/L1cWXHN8 Jyfg== X-Forwarded-Encrypted: i=1; AJvYcCX5ZmJQ5Uh3jmTR0folSVXqPRkJAC/QZvTXpjcCiJ8VzDoY5Ab9yzargzt57D8I4js6OUoQD0iajw45r/NerlKKUUeE8D7Ks9NrZ5cDQRX1hjfzK9Q= X-Gm-Message-State: AOJu0Yzmuv136BCDVM9le8mbK4T7JZRiJLdWGTih92lw0XhoybbeZZ6T b4ST6OGhZdmjDxlvhV5ynPGUn4eRKf4i7bxcXkf27qEDlWcZdhhxi/FzqkkJAmg= X-Google-Smtp-Source: AGHT+IFsshOXCXHl2FwpJZDr74IVz6qa4XzpSU8GVhBvy+WZyILZMJdKv/yipLbEuWVS+aB9wtcpOA== X-Received: by 2002:a2e:7c03:0:b0:2ec:4aac:8fd6 with SMTP id 38308e7fff4ca-2ec5b36b940mr85306941fa.10.1719499486053; Thu, 27 Jun 2024 07:44:46 -0700 (PDT) Received: from umbar.lan ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-2ee4a34447fsm2775911fa.11.2024.06.27.07.44.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Jun 2024 07:44:45 -0700 (PDT) From: Dmitry Baryshkov Date: Thu, 27 Jun 2024 17:44:42 +0300 Subject: [PATCH v4 3/7] usb: typec: ucsi: split read operation MIME-Version: 1.0 Message-Id: <20240627-ucsi-rework-interface-v4-3-289ddc6874c7@linaro.org> References: <20240627-ucsi-rework-interface-v4-0-289ddc6874c7@linaro.org> In-Reply-To: <20240627-ucsi-rework-interface-v4-0-289ddc6874c7@linaro.org> To: Heikki Krogerus , Greg Kroah-Hartman , Maxime Coquelin , Alexandre Torgue Cc: Nikita Travkin , Neil Armstrong , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=17090; i=dmitry.baryshkov@linaro.org; h=from:subject:message-id; bh=ngrfxb9LgQo60Yk99ph8ipR6eAAXUwAD0pFIgQOxGvs=; b=owEBbQGS/pANAwAKAYs8ij4CKSjVAcsmYgBmfXrZCfhNE5yevor8AbbbZlfy46bcJny6xgLVy cgpuUMp3a6JATMEAAEKAB0WIQRMcISVXLJjVvC4lX+LPIo+Aiko1QUCZn162QAKCRCLPIo+Aiko 1fgGB/47D94ko774U9MqWLJY7Ou/4dkmzpzrKWfS8mEh5jMI9+OVaoc+25I05KAh6jjT/5SlysK aV5BQ+c1XDuhDsbIf83kPUW12xQ40NT0JhKbkmCfyx6ulqt/XD9hdrXGZy2VPcZTNl3Qg0iv23D GSxEdrGhgbNeV+SMrtPPXaC0WUW7kptY+bU80RrbIn/Y0mu5l49TFWdLU6OrP7gMl/+9t1ckW8y pv1mpw7zbXQct0FtUd7zFmYETBB00tjiDtGy9+wlETEk8cCwR0ZJ4Az74HsEn+V9RrphD5C4Qg7 rPnMmY0457Mcs8IFa5iFec1G1iAdBZY1SmTGFKtff5iRwuUA X-Developer-Key: i=dmitry.baryshkov@linaro.org; a=openpgp; fpr=8F88381DD5C873E4AE487DA5199BF1243632046A X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240627_074453_834707_5BBA65A9 X-CRM114-Status: GOOD ( 20.33 ) 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 The read operation is only used to read fixed data at fixed offsets (UCSI_VERSION, UCSI_CCI, UCSI_MESSAGE_IN). In some cases drivers apply offset-specific overrides. Split the read() operation into three operations, read_version(), read_cci(), read_message_in(). Tested-by: Heikki Krogerus Reviewed-by: Heikki Krogerus Signed-off-by: Dmitry Baryshkov --- drivers/usb/typec/ucsi/ucsi.c | 20 ++++----- drivers/usb/typec/ucsi/ucsi.h | 9 +++-- drivers/usb/typec/ucsi/ucsi_acpi.c | 72 ++++++++++++++++++++++++++------- drivers/usb/typec/ucsi/ucsi_ccg.c | 50 ++++++++++++----------- drivers/usb/typec/ucsi/ucsi_glink.c | 19 ++++++++- drivers/usb/typec/ucsi/ucsi_stm32g0.c | 19 ++++++++- drivers/usb/typec/ucsi/ucsi_yoga_c630.c | 52 +++++++++++++++--------- 7 files changed, 169 insertions(+), 72 deletions(-) diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c index e8172b7711c8..17d12c1872f6 100644 --- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -46,7 +46,7 @@ static int ucsi_read_message_in(struct ucsi *ucsi, void *buf, if (ucsi->version <= UCSI_VERSION_1_2) buf_size = clamp(buf_size, 0, 16); - return ucsi->ops->read(ucsi, UCSI_MESSAGE_IN, buf, buf_size); + return ucsi->ops->read_message_in(ucsi, buf, buf_size); } static int ucsi_acknowledge(struct ucsi *ucsi, bool conn_ack) @@ -159,7 +159,7 @@ static int ucsi_exec_command(struct ucsi *ucsi, u64 cmd) if (ret) return ret; - ret = ucsi->ops->read(ucsi, UCSI_CCI, &cci, sizeof(cci)); + ret = ucsi->ops->read_cci(ucsi, &cci); if (ret) return ret; @@ -1338,7 +1338,7 @@ static int ucsi_reset_ppm(struct ucsi *ucsi) mutex_lock(&ucsi->ppm_lock); - ret = ucsi->ops->read(ucsi, UCSI_CCI, &cci, sizeof(cci)); + ret = ucsi->ops->read_cci(ucsi, &cci); if (ret < 0) goto out; @@ -1356,8 +1356,7 @@ static int ucsi_reset_ppm(struct ucsi *ucsi) tmo = jiffies + msecs_to_jiffies(UCSI_TIMEOUT_MS); do { - ret = ucsi->ops->read(ucsi, UCSI_CCI, - &cci, sizeof(cci)); + ret = ucsi->ops->read_cci(ucsi, &cci); if (ret < 0) goto out; if (cci & UCSI_CCI_COMMAND_COMPLETE) @@ -1386,7 +1385,7 @@ static int ucsi_reset_ppm(struct ucsi *ucsi) /* Give the PPM time to process a reset before reading CCI */ msleep(20); - ret = ucsi->ops->read(ucsi, UCSI_CCI, &cci, sizeof(cci)); + ret = ucsi->ops->read_cci(ucsi, &cci); if (ret) goto out; @@ -1806,7 +1805,7 @@ static int ucsi_init(struct ucsi *ucsi) ucsi->ntfy = ntfy; mutex_lock(&ucsi->ppm_lock); - ret = ucsi->ops->read(ucsi, UCSI_CCI, &cci, sizeof(cci)); + ret = ucsi->ops->read_cci(ucsi, &cci); mutex_unlock(&ucsi->ppm_lock); if (ret) return ret; @@ -1920,7 +1919,9 @@ struct ucsi *ucsi_create(struct device *dev, const struct ucsi_operations *ops) { struct ucsi *ucsi; - if (!ops || !ops->read || !ops->sync_control || !ops->async_control) + if (!ops || + !ops->read_version || !ops->read_cci || !ops->read_message_in || + !ops->sync_control || !ops->async_control) return ERR_PTR(-EINVAL); ucsi = kzalloc(sizeof(*ucsi), GFP_KERNEL); @@ -1956,8 +1957,7 @@ int ucsi_register(struct ucsi *ucsi) { int ret; - ret = ucsi->ops->read(ucsi, UCSI_VERSION, &ucsi->version, - sizeof(ucsi->version)); + ret = ucsi->ops->read_version(ucsi, &ucsi->version); if (ret) return ret; diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h index a8c161a39f11..2560e144e158 100644 --- a/drivers/usb/typec/ucsi/ucsi.h +++ b/drivers/usb/typec/ucsi/ucsi.h @@ -56,7 +56,9 @@ struct dentry; /** * struct ucsi_operations - UCSI I/O operations - * @read: Read operation + * @read_version: Read implemented UCSI version + * @read_cci: Read CCI register + * @read_message_in: Read message data from UCSI * @sync_control: Blocking control operation * @async_control: Non-blocking control operation * @update_altmodes: Squashes duplicate DP altmodes @@ -68,8 +70,9 @@ struct dentry; * return immediately after sending the data to the PPM. */ struct ucsi_operations { - int (*read)(struct ucsi *ucsi, unsigned int offset, - void *val, size_t val_len); + int (*read_version)(struct ucsi *ucsi, u16 *version); + int (*read_cci)(struct ucsi *ucsi, u32 *cci); + int (*read_message_in)(struct ucsi *ucsi, void *val, size_t val_len); int (*sync_control)(struct ucsi *ucsi, u64 command); int (*async_control)(struct ucsi *ucsi, u64 command); bool (*update_altmodes)(struct ucsi *ucsi, struct ucsi_altmode *orig, diff --git a/drivers/usb/typec/ucsi/ucsi_acpi.c b/drivers/usb/typec/ucsi/ucsi_acpi.c index f54e4722d8f6..3660dc3e6d32 100644 --- a/drivers/usb/typec/ucsi/ucsi_acpi.c +++ b/drivers/usb/typec/ucsi/ucsi_acpi.c @@ -46,8 +46,7 @@ static int ucsi_acpi_dsm(struct ucsi_acpi *ua, int func) return 0; } -static int ucsi_acpi_read(struct ucsi *ucsi, unsigned int offset, - void *val, size_t val_len) +static int ucsi_acpi_read_version(struct ucsi *ucsi, u16 *version) { struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); int ret; @@ -56,7 +55,35 @@ static int ucsi_acpi_read(struct ucsi *ucsi, unsigned int offset, if (ret) return ret; - memcpy(val, ua->base + offset, val_len); + memcpy(version, ua->base + UCSI_VERSION, sizeof(*version)); + + return 0; +} + +static int ucsi_acpi_read_cci(struct ucsi *ucsi, u32 *cci) +{ + struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); + int ret; + + ret = ucsi_acpi_dsm(ua, UCSI_DSM_FUNC_READ); + if (ret) + return ret; + + memcpy(cci, ua->base + UCSI_CCI, sizeof(*cci)); + + return 0; +} + +static int ucsi_acpi_read_message_in(struct ucsi *ucsi, void *val, size_t val_len) +{ + struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); + int ret; + + ret = ucsi_acpi_dsm(ua, UCSI_DSM_FUNC_READ); + if (ret) + return ret; + + memcpy(val, ua->base + UCSI_MESSAGE_IN, val_len); return 0; } @@ -99,36 +126,50 @@ static int ucsi_acpi_sync_control(struct ucsi *ucsi, u64 command) } static const struct ucsi_operations ucsi_acpi_ops = { - .read = ucsi_acpi_read, + .read_version = ucsi_acpi_read_version, + .read_cci = ucsi_acpi_read_cci, + .read_message_in = ucsi_acpi_read_message_in, .sync_control = ucsi_acpi_sync_control, .async_control = ucsi_acpi_async_control }; static int -ucsi_zenbook_read(struct ucsi *ucsi, unsigned int offset, void *val, size_t val_len) +ucsi_zenbook_read_cci(struct ucsi *ucsi, u32 *cci) { struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); int ret; - if (offset == UCSI_VERSION || UCSI_COMMAND(ua->cmd) == UCSI_PPM_RESET) { + if (UCSI_COMMAND(ua->cmd) == UCSI_PPM_RESET) { ret = ucsi_acpi_dsm(ua, UCSI_DSM_FUNC_READ); if (ret) return ret; } - memcpy(val, ua->base + offset, val_len); + memcpy(cci, ua->base + UCSI_CCI, sizeof(*cci)); + + return 0; +} + +static int +ucsi_zenbook_read_message_in(struct ucsi *ucsi, void *val, size_t val_len) +{ + struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); + + /* UCSI_MESSAGE_IN is never read for PPM_RESET, return stored data */ + memcpy(val, ua->base + UCSI_MESSAGE_IN, val_len); return 0; } static const struct ucsi_operations ucsi_zenbook_ops = { - .read = ucsi_zenbook_read, + .read_version = ucsi_acpi_read_version, + .read_cci = ucsi_zenbook_read_cci, + .read_message_in = ucsi_zenbook_read_message_in, .sync_control = ucsi_acpi_sync_control, .async_control = ucsi_acpi_async_control }; -static int ucsi_gram_read(struct ucsi *ucsi, unsigned int offset, - void *val, size_t val_len) +static int ucsi_gram_read_message_in(struct ucsi *ucsi, void *val, size_t val_len) { u16 bogus_change = UCSI_CONSTAT_POWER_LEVEL_CHANGE | UCSI_CONSTAT_PDOS_CHANGE; @@ -136,13 +177,12 @@ static int ucsi_gram_read(struct ucsi *ucsi, unsigned int offset, struct ucsi_connector_status *status; int ret; - ret = ucsi_acpi_read(ucsi, offset, val, val_len); + ret = ucsi_acpi_read_message_in(ucsi, val, val_len); if (ret < 0) return ret; if (UCSI_COMMAND(ua->cmd) == UCSI_GET_CONNECTOR_STATUS && - test_bit(UCSI_ACPI_CHECK_BOGUS_EVENT, &ua->flags) && - offset == UCSI_MESSAGE_IN) { + test_bit(UCSI_ACPI_CHECK_BOGUS_EVENT, &ua->flags)) { status = (struct ucsi_connector_status *)val; /* Clear the bogus change */ @@ -173,7 +213,9 @@ static int ucsi_gram_sync_control(struct ucsi *ucsi, u64 command) } static const struct ucsi_operations ucsi_gram_ops = { - .read = ucsi_gram_read, + .read_version = ucsi_acpi_read_version, + .read_cci = ucsi_acpi_read_cci, + .read_message_in = ucsi_gram_read_message_in, .sync_control = ucsi_gram_sync_control, .async_control = ucsi_acpi_async_control }; @@ -203,7 +245,7 @@ static void ucsi_acpi_notify(acpi_handle handle, u32 event, void *data) u32 cci; int ret; - ret = ua->ucsi->ops->read(ua->ucsi, UCSI_CCI, &cci, sizeof(cci)); + ret = ua->ucsi->ops->read_cci(ua->ucsi, &cci); if (ret) return; diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c index 76b39bb9762d..6ccc394f268e 100644 --- a/drivers/usb/typec/ucsi/ucsi_ccg.c +++ b/drivers/usb/typec/ucsi/ucsi_ccg.c @@ -556,32 +556,34 @@ static void ucsi_ccg_nvidia_altmode(struct ucsi_ccg *uc, } } -static int ucsi_ccg_read(struct ucsi *ucsi, unsigned int offset, - void *val, size_t val_len) +static int ucsi_ccg_read_version(struct ucsi *ucsi, u16 *version) { struct ucsi_ccg *uc = ucsi_get_drvdata(ucsi); - u16 reg = CCGX_RAB_UCSI_DATA_BLOCK(offset); - struct ucsi_capability *cap; - struct ucsi_altmode *alt; - int ret = 0; + u16 reg = CCGX_RAB_UCSI_DATA_BLOCK(UCSI_VERSION); - if (offset == UCSI_CCI) { - spin_lock(&uc->op_lock); - memcpy(val, &(uc->op_data).cci, val_len); - spin_unlock(&uc->op_lock); - } else if (offset == UCSI_MESSAGE_IN) { - spin_lock(&uc->op_lock); - memcpy(val, &(uc->op_data).message_in, val_len); - spin_unlock(&uc->op_lock); - } else { - ret = ccg_read(uc, reg, val, val_len); - } + return ccg_read(uc, reg, (u8 *)version, sizeof(*version)); +} - if (ret) - return ret; +static int ucsi_ccg_read_cci(struct ucsi *ucsi, u32 *cci) +{ + struct ucsi_ccg *uc = ucsi_get_drvdata(ucsi); - if (offset != UCSI_MESSAGE_IN) - return ret; + spin_lock(&uc->op_lock); + *cci = uc->op_data.cci; + spin_unlock(&uc->op_lock); + + return 0; +} + +static int ucsi_ccg_read_message_in(struct ucsi *ucsi, void *val, size_t val_len) +{ + struct ucsi_ccg *uc = ucsi_get_drvdata(ucsi); + struct ucsi_capability *cap; + struct ucsi_altmode *alt; + + spin_lock(&uc->op_lock); + memcpy(val, uc->op_data.message_in, val_len); + spin_unlock(&uc->op_lock); switch (UCSI_COMMAND(uc->last_cmd_sent)) { case UCSI_GET_CURRENT_CAM: @@ -607,7 +609,7 @@ static int ucsi_ccg_read(struct ucsi *ucsi, unsigned int offset, } uc->last_cmd_sent = 0; - return ret; + return 0; } static int ucsi_ccg_async_control(struct ucsi *ucsi, u64 command) @@ -663,7 +665,9 @@ static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command) } static const struct ucsi_operations ucsi_ccg_ops = { - .read = ucsi_ccg_read, + .read_version = ucsi_ccg_read_version, + .read_cci = ucsi_ccg_read_cci, + .read_message_in = ucsi_ccg_read_message_in, .sync_control = ucsi_ccg_sync_control, .async_control = ucsi_ccg_async_control, .update_altmodes = ucsi_ccg_update_altmodes diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c index ebd76257c4fc..56bad054e78f 100644 --- a/drivers/usb/typec/ucsi/ucsi_glink.c +++ b/drivers/usb/typec/ucsi/ucsi_glink.c @@ -114,6 +114,21 @@ static int pmic_glink_ucsi_read(struct ucsi *__ucsi, unsigned int offset, return ret; } +static int pmic_glink_ucsi_read_version(struct ucsi *ucsi, u16 *version) +{ + return pmic_glink_ucsi_read(ucsi, UCSI_VERSION, version, sizeof(*version)); +} + +static int pmic_glink_ucsi_read_cci(struct ucsi *ucsi, u32 *cci) +{ + return pmic_glink_ucsi_read(ucsi, UCSI_CCI, cci, sizeof(*cci)); +} + +static int pmic_glink_ucsi_read_message_in(struct ucsi *ucsi, void *val, size_t val_len) +{ + return pmic_glink_ucsi_read(ucsi, UCSI_MESSAGE_IN, val, val_len); +} + static int pmic_glink_ucsi_locked_write(struct pmic_glink_ucsi *ucsi, unsigned int offset, const void *val, size_t val_len) { @@ -214,7 +229,9 @@ static void pmic_glink_ucsi_connector_status(struct ucsi_connector *con) } static const struct ucsi_operations pmic_glink_ucsi_ops = { - .read = pmic_glink_ucsi_read, + .read_version = pmic_glink_ucsi_read_version, + .read_cci = pmic_glink_ucsi_read_cci, + .read_message_in = pmic_glink_ucsi_read_message_in, .sync_control = pmic_glink_ucsi_sync_control, .async_control = pmic_glink_ucsi_async_control, .update_connector = pmic_glink_ucsi_update_connector, diff --git a/drivers/usb/typec/ucsi/ucsi_stm32g0.c b/drivers/usb/typec/ucsi/ucsi_stm32g0.c index 396e2090e7c3..14737ca3724c 100644 --- a/drivers/usb/typec/ucsi/ucsi_stm32g0.c +++ b/drivers/usb/typec/ucsi/ucsi_stm32g0.c @@ -359,6 +359,21 @@ static int ucsi_stm32g0_read(struct ucsi *ucsi, unsigned int offset, void *val, return 0; } +static int ucsi_stm32g0_read_version(struct ucsi *ucsi, u16 *version) +{ + return ucsi_stm32g0_read(ucsi, UCSI_VERSION, version, sizeof(*version)); +} + +static int ucsi_stm32g0_read_cci(struct ucsi *ucsi, u32 *cci) +{ + return ucsi_stm32g0_read(ucsi, UCSI_CCI, cci, sizeof(*cci)); +} + +static int ucsi_stm32g0_read_message_in(struct ucsi *ucsi, void *val, size_t len) +{ + return ucsi_stm32g0_read(ucsi, UCSI_MESSAGE_IN, val, len); +} + static int ucsi_stm32g0_async_control(struct ucsi *ucsi, u64 command) { struct ucsi_stm32g0 *g0 = ucsi_get_drvdata(ucsi); @@ -446,7 +461,9 @@ static irqreturn_t ucsi_stm32g0_irq_handler(int irq, void *data) } static const struct ucsi_operations ucsi_stm32g0_ops = { - .read = ucsi_stm32g0_read, + .read_version = ucsi_stm32g0_read_version, + .read_cci = ucsi_stm32g0_read_cci, + .read_message_in = ucsi_stm32g0_read_message_in, .sync_control = ucsi_stm32g0_sync_control, .async_control = ucsi_stm32g0_async_control, }; diff --git a/drivers/usb/typec/ucsi/ucsi_yoga_c630.c b/drivers/usb/typec/ucsi/ucsi_yoga_c630.c index e5e8ba0c0eaa..95a333ad5496 100644 --- a/drivers/usb/typec/ucsi/ucsi_yoga_c630.c +++ b/drivers/usb/typec/ucsi/ucsi_yoga_c630.c @@ -27,8 +27,16 @@ struct yoga_c630_ucsi { u16 version; }; -static int yoga_c630_ucsi_read(struct ucsi *ucsi, unsigned int offset, - void *val, size_t val_len) +static int yoga_c630_ucsi_read_version(struct ucsi *ucsi, u16 *version) +{ + struct yoga_c630_ucsi *uec = ucsi_get_drvdata(ucsi); + + *version = uec->version; + + return 0; +} + +static int yoga_c630_ucsi_read_cci(struct ucsi *ucsi, u32 *cci) { struct yoga_c630_ucsi *uec = ucsi_get_drvdata(ucsi); u8 buf[YOGA_C630_UCSI_READ_SIZE]; @@ -38,22 +46,26 @@ static int yoga_c630_ucsi_read(struct ucsi *ucsi, unsigned int offset, if (ret) return ret; - if (offset == UCSI_VERSION) { - memcpy(val, &uec->version, min(val_len, sizeof(uec->version))); - return 0; - } + memcpy(cci, buf, sizeof(*cci)); - switch (offset) { - case UCSI_CCI: - memcpy(val, buf, min(val_len, YOGA_C630_UCSI_CCI_SIZE)); - return 0; - case UCSI_MESSAGE_IN: - memcpy(val, buf + YOGA_C630_UCSI_CCI_SIZE, - min(val_len, YOGA_C630_UCSI_DATA_SIZE)); - return 0; - default: - return -EINVAL; - } + return 0; +} + +static int yoga_c630_ucsi_read_message_in(struct ucsi *ucsi, + void *val, size_t val_len) +{ + struct yoga_c630_ucsi *uec = ucsi_get_drvdata(ucsi); + u8 buf[YOGA_C630_UCSI_READ_SIZE]; + int ret; + + ret = yoga_c630_ec_ucsi_read(uec->ec, buf); + if (ret) + return ret; + + memcpy(val, buf + YOGA_C630_UCSI_CCI_SIZE, + min(val_len, YOGA_C630_UCSI_DATA_SIZE)); + + return 0; } static int yoga_c630_ucsi_async_control(struct ucsi *ucsi, u64 command) @@ -93,7 +105,9 @@ static int yoga_c630_ucsi_sync_control(struct ucsi *ucsi, u64 command) } const struct ucsi_operations yoga_c630_ucsi_ops = { - .read = yoga_c630_ucsi_read, + .read_version = yoga_c630_ucsi_read_version, + .read_cci = yoga_c630_ucsi_read_cci, + .read_message_in = yoga_c630_ucsi_read_message_in, .sync_control = yoga_c630_ucsi_sync_control, .async_control = yoga_c630_ucsi_async_control, }; @@ -126,7 +140,7 @@ static int yoga_c630_ucsi_notify(struct notifier_block *nb, return NOTIFY_OK; case LENOVO_EC_EVENT_UCSI: - ret = uec->ucsi->ops->read(uec->ucsi, UCSI_CCI, &cci, sizeof(cci)); + ret = uec->ucsi->ops->read_cci(uec->ucsi, &cci); if (ret) return NOTIFY_DONE; From patchwork Thu Jun 27 14:44:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13714511 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 7D679C3064D for ; Thu, 27 Jun 2024 14:45:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References :Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=Pv3PctyJy2SnI13bqUyVzb7EmYqWrJDar658iy+XONk=; b=xPHd3WuCl2m72p86VAWo5Tm4z/ +RfUaYhedS+ahsnXrk7W/BYHP2zFzt7eCZQFUuOR2L0jzDKYE/ZIp+XuboV8S84qtq/jiGyzWUF1v sAma31CJyGntb8SLvIlW+4Wky7WabkYQ3vssYOgtsB0rmSXPdV/xlm3CVHuLHLLPMaNtH7WkdMj65 Lv/rlk1k2v5vpTwMjSwrinTpPLHGRpsEdWUSWh2Glai6nGIvyUCIFcCcAIq5tMeZ4faFmV6GVy+Uh 3hnFhtfGlO5NO6hoyCFDlALUr0rCN4ROok21Izo322xQldKjlK+elm8+8qS/Rrd6hyvBHSgQ2EStE yTi/3g/A==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sMqNY-0000000Agjm-3sM0; Thu, 27 Jun 2024 14:45:40 +0000 Received: from mail-lj1-x230.google.com ([2a00:1450:4864:20::230]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sMqMo-0000000AgLr-2xrt for linux-arm-kernel@lists.infradead.org; Thu, 27 Jun 2024 14:44:58 +0000 Received: by mail-lj1-x230.google.com with SMTP id 38308e7fff4ca-2ec58040f39so55418381fa.2 for ; Thu, 27 Jun 2024 07:44:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1719499487; x=1720104287; darn=lists.infradead.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=Pv3PctyJy2SnI13bqUyVzb7EmYqWrJDar658iy+XONk=; b=fIg3dSqYRLFEtZcaLQyfDCCzWsxT0G2T8cpJzTNj6mDv56t00nYDrE6AAc9Ziflmcy sTEiSKMecICz95JkbQR3+ESmNru7ZrWQRBFu2SiWBXWq5w6Lbxq2KsEoPNzzSUnrrB6L P1P/vFpptbnd0AfMuMZHoqAdU2jLxb9ItZSHwFfEbwC3lUMgl5ISm3nmaZ2e1HrbkDpb ohG8tvL5GAtzNEZHqFYu8x0Dsh+QUa4Aus/49cq0hx4NZQnNM+yOnJQUSX2fbr3vj+cm 6rcV3PDk3r053QQ56OXiCW1ZwBGOGaonf2/Kovx0wuAWhrATgOZCWV/iR6cC6Y9f7FQ6 uA8A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719499487; x=1720104287; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Pv3PctyJy2SnI13bqUyVzb7EmYqWrJDar658iy+XONk=; b=QmhTbipdZl69yA6fzEZQFXHWSO0MtxvErHDLXRPMIi7CUtniiKis/IvQB3l/jugcNR Ob3ZZ575z4KJgV3T2aMwBn310jEK17FOuzYN6ryYGj9+tM61EEXHysGvAtkLgVVyVJOn Bfyr84TbpfgvghQUtrvuGVQmbh9XKxMOSLdL8YoJphNExOXU6KsdmVbPGtcoxLpIDS2e 0hT/HeG+R1m2DA62k4b9225tOS+GBM+ZiaG1A+DGLID2ywVhGtHNm4EXsVeA68U4rrx6 Hr4ALhISs4UQN5boFsq/N7kbGChEQLv5hmC18lzC8u6B0Xle6RkI7Ynrng/LBXdiW7mR yv8Q== X-Forwarded-Encrypted: i=1; AJvYcCUP2Q9QXDdou9KIzpUnEoZlBVUsv94cRzhuORpEg8nrP3MourMO1yFbx98MzYwwdCpnEHYdjNnTxOn2VHmz94pWnPJgZZqcaw7Y2MRxKUWKYb+CXmc= X-Gm-Message-State: AOJu0YyyC7ewZ+Doaa1TuMJ68p6z17veUwltSYU6jvomqWIUat0/OmER VCVj0dBplj5NMw5mD9CDSg+j1VWZ2MIKNLypGfILuKWSVDxyizkKp4/5iNbZLl0= X-Google-Smtp-Source: AGHT+IGyKCad0pTtyjWDWYT4auTNDLJlAquHp5LlnqVILjGBHWKp/6jvkXxkAFrJTEFJQT7zvH22Gw== X-Received: by 2002:a2e:b004:0:b0:2eb:ebcd:fc1c with SMTP id 38308e7fff4ca-2ec594034bbmr78292621fa.26.1719499486745; Thu, 27 Jun 2024 07:44:46 -0700 (PDT) Received: from umbar.lan ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-2ee4a34447fsm2775911fa.11.2024.06.27.07.44.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Jun 2024 07:44:46 -0700 (PDT) From: Dmitry Baryshkov Date: Thu, 27 Jun 2024 17:44:43 +0300 Subject: [PATCH v4 4/7] usb: typec: ucsi: rework command execution functions MIME-Version: 1.0 Message-Id: <20240627-ucsi-rework-interface-v4-4-289ddc6874c7@linaro.org> References: <20240627-ucsi-rework-interface-v4-0-289ddc6874c7@linaro.org> In-Reply-To: <20240627-ucsi-rework-interface-v4-0-289ddc6874c7@linaro.org> To: Heikki Krogerus , Greg Kroah-Hartman , Maxime Coquelin , Alexandre Torgue Cc: Nikita Travkin , Neil Armstrong , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4910; i=dmitry.baryshkov@linaro.org; h=from:subject:message-id; bh=IUlRPLcwpNg8JnyGbOvllbRci0dly68y4uffDqgWHcE=; b=owEBbQGS/pANAwAKAYs8ij4CKSjVAcsmYgBmfXrZU2jPKiwjQP35+8I88ou3BxaPfkpg4PJJq onR4FOLWHaJATMEAAEKAB0WIQRMcISVXLJjVvC4lX+LPIo+Aiko1QUCZn162QAKCRCLPIo+Aiko 1cBnB/sEp9lqE76ma6UnCY7LbhqliIuPkO9FULEW8UHfMI5X8F+JdTgWpedlAKFdYNxEK48AiL5 xytAUgkAj6ceGwOp0xx/JTMBPfGy/LNlBQVvbzU1YiRjUr+lbg6H1lI80C5VvdijDo+1hnCNQRV ecEYU8muhwSmRAj0FR1SIQ10cp13vLbTdEse+BDcmnHMwMh41KT4DknuX3Pfkler5ez4oOucu5o R/9mtPjhNSLk1SkyMDxYrJIC7Tq8ds8MBqBFTnWBzsHJ3CG9sS0o7HlCr6Wj78lqxsWVId+Mv73 RrG8rgRv1c9gmbcNJ99Kk8jsDbZtPmbx4tG9QhqGFKT7lSTU X-Developer-Key: i=dmitry.baryshkov@linaro.org; a=openpgp; fpr=8F88381DD5C873E4AE487DA5199BF1243632046A X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240627_074454_801208_15410248 X-CRM114-Status: GOOD ( 15.38 ) 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 Rework command execution code to remove recursive calls of ucsi_exec_command. This also streamlines the sync_control / read(CCI) read (MESSAGE_IN) sequence, allowing further rework of the command code. Tested-by: Heikki Krogerus Reviewed-by: Heikki Krogerus Signed-off-by: Dmitry Baryshkov --- drivers/usb/typec/ucsi/ucsi.c | 138 ++++++++++++++++++++---------------------- 1 file changed, 66 insertions(+), 72 deletions(-) diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c index 17d12c1872f6..10a8fe893333 100644 --- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -63,27 +63,76 @@ static int ucsi_acknowledge(struct ucsi *ucsi, bool conn_ack) return ucsi->ops->sync_control(ucsi, ctrl); } -static int ucsi_exec_command(struct ucsi *ucsi, u64 command); +static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci, + void *data, size_t size, bool conn_ack) +{ + int ret; + + *cci = 0; + + ret = ucsi->ops->sync_control(ucsi, command); + if (ret) + return ret; + + ret = ucsi->ops->read_cci(ucsi, cci); + if (ret) + return ret; + + if (*cci & UCSI_CCI_BUSY) + return -EBUSY; + + if (!(*cci & UCSI_CCI_COMMAND_COMPLETE)) + return -EIO; + + if (*cci & UCSI_CCI_NOT_SUPPORTED) { + if (ucsi_acknowledge(ucsi, false) < 0) + dev_err(ucsi->dev, + "ACK of unsupported command failed\n"); + return -EOPNOTSUPP; + } + + if (*cci & UCSI_CCI_ERROR) { + /* Acknowledge the command that failed */ + ret = ucsi_acknowledge(ucsi, false); + return ret ? ret : -EIO; + } + + if (data) { + ret = ucsi_read_message_in(ucsi, data, size); + if (ret) + return ret; + } + + ret = ucsi_acknowledge(ucsi, conn_ack); + if (ret) + return ret; + + return 0; +} static int ucsi_read_error(struct ucsi *ucsi, u8 connector_num) { u64 command; u16 error; + u32 cci; int ret; command = UCSI_GET_ERROR_STATUS | UCSI_CONNECTOR_NUMBER(connector_num); - ret = ucsi_exec_command(ucsi, command); - if (ret < 0) - return ret; + ret = ucsi_run_command(ucsi, command, &cci, + &error, sizeof(error), false); - ret = ucsi_read_message_in(ucsi, &error, sizeof(error)); - if (ret) - return ret; + if (cci & UCSI_CCI_BUSY) { + ret = ucsi_run_command(ucsi, UCSI_CANCEL, &cci, NULL, 0, false); - ret = ucsi_acknowledge(ucsi, false); - if (ret) + return ret ? ret : -EBUSY; + } + + if (ret < 0) return ret; + if (cci & UCSI_CCI_ERROR) + return -EIO; + switch (error) { case UCSI_ERROR_INCOMPATIBLE_PARTNER: return -EOPNOTSUPP; @@ -129,7 +178,8 @@ static int ucsi_read_error(struct ucsi *ucsi, u8 connector_num) return -EIO; } -static int ucsi_exec_command(struct ucsi *ucsi, u64 cmd) +static int ucsi_send_command_common(struct ucsi *ucsi, u64 cmd, + void *data, size_t size, bool conn_ack) { u8 connector_num; u32 cci; @@ -155,73 +205,17 @@ static int ucsi_exec_command(struct ucsi *ucsi, u64 cmd) connector_num = 0; } - ret = ucsi->ops->sync_control(ucsi, cmd); - if (ret) - return ret; - - ret = ucsi->ops->read_cci(ucsi, &cci); - if (ret) - return ret; - - if (cmd != UCSI_CANCEL && cci & UCSI_CCI_BUSY) - return ucsi_exec_command(ucsi, UCSI_CANCEL); - - if (!(cci & UCSI_CCI_COMMAND_COMPLETE)) - return -EIO; - - if (cci & UCSI_CCI_NOT_SUPPORTED) { - if (ucsi_acknowledge(ucsi, false) < 0) - dev_err(ucsi->dev, - "ACK of unsupported command failed\n"); - return -EOPNOTSUPP; - } - - if (cci & UCSI_CCI_ERROR) { - /* Acknowledge the command that failed */ - ret = ucsi_acknowledge(ucsi, false); - if (ret) - return ret; - - if (cmd == UCSI_GET_ERROR_STATUS) - return -EIO; - - return ucsi_read_error(ucsi, connector_num); - } - - if (cmd == UCSI_CANCEL && cci & UCSI_CCI_CANCEL_COMPLETE) { - ret = ucsi_acknowledge(ucsi, false); - return ret ? ret : -EBUSY; - } - - return UCSI_CCI_LENGTH(cci); -} - -static int ucsi_send_command_common(struct ucsi *ucsi, u64 command, - void *data, size_t size, bool conn_ack) -{ - u8 length; - int ret; - mutex_lock(&ucsi->ppm_lock); - ret = ucsi_exec_command(ucsi, command); - if (ret < 0) - goto out; - - length = ret; - - if (data) { - ret = ucsi_read_message_in(ucsi, data, size); - if (ret) - goto out; + ret = ucsi_run_command(ucsi, cmd, &cci, data, size, conn_ack); + if (cci & UCSI_CCI_BUSY) { + ret = ucsi_run_command(ucsi, UCSI_CANCEL, &cci, NULL, 0, false); + return ret ? ret : -EBUSY; } - ret = ucsi_acknowledge(ucsi, conn_ack); - if (ret) - goto out; + if (cci & UCSI_CCI_ERROR) + return ucsi_read_error(ucsi, connector_num); - ret = length; -out: mutex_unlock(&ucsi->ppm_lock); return ret; } From patchwork Thu Jun 27 14:44:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13714507 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 5CB45C2BD09 for ; Thu, 27 Jun 2024 14:45:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References :Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=efQFGr6jGBKjwmMdwj9cOaioErJGFDxQ/6GTKiEu6I8=; b=1xE2/GGcK8oXQcjODA/B4idDRO 0+nA9tckKPYCI647JVbhP5l/bMHTrrNs4x7+4WBcWhq5bvw88d67mnnQu58zO0Cm2xs60k/iRftKF frSdAvSMXsjCGvtsCh43FfcUdp4l+/c+El8bm6J82NF/Xm4FKqsxkwKwkdEmCjG017rYxx7pJAbN9 9515uzLqDFGoMEKRPUQWksa2QvKgRAqrIr/j6LwZZYTWlqwnlOSkq7e9vbi1mdKgl/yf3ArpccOSZ /CckPo788xEWJGBaHSpoABZgjIXJ2M5ZQ+Y3cj6SSJkWBri/oUr7ylL9zM86fsSAXvctOzUT838ml Vw0w4SrQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sMqN8-0000000AgUF-1MAL; Thu, 27 Jun 2024 14:45:14 +0000 Received: from mail-lj1-x232.google.com ([2a00:1450:4864:20::232]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sMqMo-0000000AgLs-2y4o for linux-arm-kernel@lists.infradead.org; Thu, 27 Jun 2024 14:44:57 +0000 Received: by mail-lj1-x232.google.com with SMTP id 38308e7fff4ca-2ec4eefbaf1so73419821fa.1 for ; Thu, 27 Jun 2024 07:44:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1719499487; x=1720104287; darn=lists.infradead.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=efQFGr6jGBKjwmMdwj9cOaioErJGFDxQ/6GTKiEu6I8=; b=LjJ2Yto5cdZX6tEGLzTmPHV9do1IHytzTrV2IOe5TlgPdZPvkVQVuJ6jP9yqseCPmB iOrI9sfE1DD+U7NPRorq1sGZd1go7lwBO/a1FotSl3tzSIZIB53iJZsLF8VauXRWovI1 965GVzRyy8gMKqhduRR4GBZrD/HFI4zmATdYqI1nkHoZFSQm9hepQT8SAsJLwCXC1XLZ tnK9qOwV0X0BgonMM6Soj7S1OK4700UJe17Xv2hG33hfzVsz1DVxULdGsCdnZ5N/s+UE 5JILhoexxqvAIhkKJQmjgTCezo/J2/OPVoa+C2aQ6Z8OVrc56Z+QxjQ1svRmfLMjYLrJ eoUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719499487; x=1720104287; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=efQFGr6jGBKjwmMdwj9cOaioErJGFDxQ/6GTKiEu6I8=; b=AL9l5rY61zgMOxUJouy7IX5tYoQSkE9P7at2c4U02CpqHC19vm0zJg+ggb0WvMjfXe T/ptMmldsex8/6i0qfS0jLj0bNg8grKnph5FxWVUM/yg683XmZ4urw144/RYkaLRpaiX Rq/lR3HUKNAjJN/9eG3Kfsq13Yl2EZFzuQkIOJl3HWzMP7mdCT1pplNT2y0bz87s9ysv qTvlSILeznk7NGlca9rIl44wwEnZYR3I7yIUCflKKbWwJ66oSpsyfAnrOURBJxXLaLbZ M6YeoghbGMjngtBWjX/tkr5Uu5TpvD+DQow5QBaRCrDFCunWrUUO0bWJapYjViSRQt3m 5XAg== X-Forwarded-Encrypted: i=1; AJvYcCV+oegXTjLXCjGofDLYNKpMTYHGTfKYjRSMmbfSd7UF2qPAotm4GSuF2WzRL87PIt495AJ3M0d+ncDbTK6Bi2Knilj6hZeLxUb/8gdkf7JfSV7PuR0= X-Gm-Message-State: AOJu0Yy2wBMJXXBgi6BaBtxW5QnDxAlbXUVJslXzOuvIzNJybT+8IeIe HP0qaMbuB20kOLtr1uq+PpAMyYJo670p2Wi5enzZYp+qE0u4VCD23hZjAk0hEdM= X-Google-Smtp-Source: AGHT+IEEpm4AxqCI4MvWw10l4nicg9YGmxodxCLh1opitXtQr+B6jBW4EVR2xxnMzOMkHx2ZA4GduA== X-Received: by 2002:a2e:9e96:0:b0:2ec:588d:7eb8 with SMTP id 38308e7fff4ca-2ec5b37a303mr79821721fa.21.1719499487664; Thu, 27 Jun 2024 07:44:47 -0700 (PDT) Received: from umbar.lan ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-2ee4a34447fsm2775911fa.11.2024.06.27.07.44.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Jun 2024 07:44:47 -0700 (PDT) From: Dmitry Baryshkov Date: Thu, 27 Jun 2024 17:44:44 +0300 Subject: [PATCH v4 5/7] usb: typec: ucsi: inline ucsi_read_message_in MIME-Version: 1.0 Message-Id: <20240627-ucsi-rework-interface-v4-5-289ddc6874c7@linaro.org> References: <20240627-ucsi-rework-interface-v4-0-289ddc6874c7@linaro.org> In-Reply-To: <20240627-ucsi-rework-interface-v4-0-289ddc6874c7@linaro.org> To: Heikki Krogerus , Greg Kroah-Hartman , Maxime Coquelin , Alexandre Torgue Cc: Nikita Travkin , Neil Armstrong , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1732; i=dmitry.baryshkov@linaro.org; h=from:subject:message-id; bh=SvL4pINrFSRfen69Stj/4WrpwjGf+jKWJ5TFSri6EH8=; b=owEBbQGS/pANAwAKAYs8ij4CKSjVAcsmYgBmfXrZIK3sNxYmewLsvSN+DxSJY8UC0w0Xoamap /iSt4ILkayJATMEAAEKAB0WIQRMcISVXLJjVvC4lX+LPIo+Aiko1QUCZn162QAKCRCLPIo+Aiko 1TewB/0eEGE2cnF0wQ2wiEEsma6QExZ1Yav41XkW8NpVgs9JLW96sutdqzAxS5BpJsP1PoyaRCD lVRCv4c2T2eHdMrZRGrTExG691TNA1w2rDx/gDgFf7lEdxtOwgxSmsxk+CZrGAP00z9k5kHoWNY Vl0IFKa8sP3qSpbB0wkrpjQtK2vRBUgU4B8WqycBSdLOhQ+exl7xVKHjc0No1McFtSOU7arST9a zqlmROo8rQ3p1nZ3ASP///xGQKpo21+K1ATF8ekM5/kHEdhrW88lVnMrvqP88SBLbPnauJG13pH e5DyIzX3Lb9EIQqQgnWEHAhv8mFDrOhGm+yKzc1znzn2VMcp X-Developer-Key: i=dmitry.baryshkov@linaro.org; a=openpgp; fpr=8F88381DD5C873E4AE487DA5199BF1243632046A X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240627_074454_790404_FA63FF73 X-CRM114-Status: GOOD ( 12.58 ) 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 There is no need to have a separate wrapper for reading MESSAGE_IN data, inline it to ucsi_run_command(). Tested-by: Heikki Krogerus Reviewed-by: Heikki Krogerus Signed-off-by: Dmitry Baryshkov --- drivers/usb/typec/ucsi/ucsi.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c index 10a8fe893333..2d87fe277c62 100644 --- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -36,19 +36,6 @@ */ #define UCSI_SWAP_TIMEOUT_MS 5000 -static int ucsi_read_message_in(struct ucsi *ucsi, void *buf, - size_t buf_size) -{ - /* - * Below UCSI 2.0, MESSAGE_IN was limited to 16 bytes. Truncate the - * reads here. - */ - if (ucsi->version <= UCSI_VERSION_1_2) - buf_size = clamp(buf_size, 0, 16); - - return ucsi->ops->read_message_in(ucsi, buf, buf_size); -} - static int ucsi_acknowledge(struct ucsi *ucsi, bool conn_ack) { u64 ctrl; @@ -70,6 +57,13 @@ static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci, *cci = 0; + /* + * Below UCSI 2.0, MESSAGE_IN was limited to 16 bytes. Truncate the + * reads here. + */ + if (ucsi->version <= UCSI_VERSION_1_2) + size = clamp(size, 0, 16); + ret = ucsi->ops->sync_control(ucsi, command); if (ret) return ret; @@ -98,7 +92,7 @@ static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci, } if (data) { - ret = ucsi_read_message_in(ucsi, data, size); + ret = ucsi->ops->read_message_in(ucsi, data, size); if (ret) return ret; } From patchwork Thu Jun 27 14:44:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13714510 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 173AAC2BD09 for ; Thu, 27 Jun 2024 14:45:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References :Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=oNtBr7H/4KEA0lX1DXTpcBNEvKkptuFVb7g1QTFBXKE=; b=icVvw7Fia0b0bwcJNESkIp6uNY EbcdPjucq1VJX/jzQb8hxHyTim5haeKQJBBVBPAfmDPFw2qfCD12+A+1S0eWSlDENUezfi7YpQG4D AR54ORfhud6ZpTfs2QuBhEY0JQ8GJzkcqNTuHAyOAUQ8l556ZFoP3g7AjhCunNrzjsen8kmmCeIcs YlZ4TGOzXYWoRFCBIuU5N4wfd/nRuhtdqdC5N+uxpCnPr/NHfGHDzd3BRr1gE4gpMnnTyteW7JLCJ PAPVN4YAJ3nr8x6rnUQdPdKdngvPqlG3RZAv6zmAg1Bze4n+jqG4hFzPB4TjWxB9Fpg7qP8Tw2EQO L1zJqrrg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sMqNS-0000000Agg5-1Pku; Thu, 27 Jun 2024 14:45:34 +0000 Received: from mail-lj1-x22a.google.com ([2a00:1450:4864:20::22a]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sMqMn-0000000AgLu-2qgU for linux-arm-kernel@lists.infradead.org; Thu, 27 Jun 2024 14:44:58 +0000 Received: by mail-lj1-x22a.google.com with SMTP id 38308e7fff4ca-2eabd22d3f4so96541871fa.1 for ; Thu, 27 Jun 2024 07:44:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1719499489; x=1720104289; darn=lists.infradead.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=oNtBr7H/4KEA0lX1DXTpcBNEvKkptuFVb7g1QTFBXKE=; b=oT3VaJoBIFPXQRM+ap4k6TfWzpEo3E+HTuWl6xRRZSOP2eXlLm7rTlVyo5AvNBeyQh LDInAcQeCTDc4f0cCl2AyyKcDlQpPjF7MLLW92gbxOug2CE9U2g2GuhTlXWVAkt/Jgf9 k0QMrI9mGJBf6biBWld1ejRaikb130aoxex1GuP31u/pJWklyBB7IS/Sac9krQTuAqF4 /AmrR6s91GF9EzcN72FyHpyjqgRVSd4TcqcNPLJ4LuRja1bPaYJlGnQt809jYtUsrj0B Y6dKg4tIlWOFBAuLh+Sds4o16KO99R0i9TPls/JUSRQOVGn0UP/k2kFPs8+1K0cL3FE3 LqHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719499489; x=1720104289; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=oNtBr7H/4KEA0lX1DXTpcBNEvKkptuFVb7g1QTFBXKE=; b=ko5mK1U/8VWjEh061DAYFtNvIhGKodb4KPH8GK5pRS9XRNctXMOTifSE6E/z84I2zr 3JiiqDGuDY7PdqwjRRg8kUE03iVOxZvENJahn0aljFJ1erasgbrUiP8A3hhqgQJeICoW miugZLyI2E0AXps+BHMyZvZk5O8StKtyEMa6QZm/M1SXFeQyrpT8h8VxB74Hva1sN1ar Nve5NrjkAgK0uF+tCWAAZArVNzCIEHyMPC6L9CU2goZIV19oVVmnJYL/ix1g7gcHFJva RlUEo96OQL3QP6SJxb3nKDNWsN05UMiHS8jyj+Wr8jVivRTio080hfP2SzTr5I+w6Z53 WfRw== X-Forwarded-Encrypted: i=1; AJvYcCV5bIw41kGvB0zTuLO2TqCXbGYTHT3yGpR4PEZIq/Bw2MKcwvNjIZqatzdrNUtu6q0iQftg6VH33sOeRuGkX2/wSW4h8oRzHpsL2gM0+s717PSngRs= X-Gm-Message-State: AOJu0YyAOBCMS7KWORVOVbHmlvFCNt6DzyP7nhiISJNjV4xZEVWvzGh4 Pak/CMYs+f9JHReq02tTgdWvu/iZ6xPXk7vZxWDXKTbyg55W4A4ue9iXaVqs2a8= X-Google-Smtp-Source: AGHT+IG/vhBiPKr5H4VT6VZmk2uUGM/u22Kql0wRoMQv2jlBGgqfEGeeogNI1eT58eYyoTwcxeXGpA== X-Received: by 2002:a2e:b616:0:b0:2ee:4eb8:2f15 with SMTP id 38308e7fff4ca-2ee4eb83097mr3650321fa.29.1719499488733; Thu, 27 Jun 2024 07:44:48 -0700 (PDT) Received: from umbar.lan ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-2ee4a34447fsm2775911fa.11.2024.06.27.07.44.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Jun 2024 07:44:48 -0700 (PDT) From: Dmitry Baryshkov Date: Thu, 27 Jun 2024 17:44:45 +0300 Subject: [PATCH v4 6/7] usb: typec: ucsi: extract common code for command handling MIME-Version: 1.0 Message-Id: <20240627-ucsi-rework-interface-v4-6-289ddc6874c7@linaro.org> References: <20240627-ucsi-rework-interface-v4-0-289ddc6874c7@linaro.org> In-Reply-To: <20240627-ucsi-rework-interface-v4-0-289ddc6874c7@linaro.org> To: Heikki Krogerus , Greg Kroah-Hartman , Maxime Coquelin , Alexandre Torgue Cc: Nikita Travkin , Neil Armstrong , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=18771; i=dmitry.baryshkov@linaro.org; h=from:subject:message-id; bh=1J+2LdyyVLafDrHe8LpC5Gnoz1i0ukS2WsUPaS+h1Z4=; b=owGbwMvMwMXYbdNlx6SpcZXxtFoSQ1pt1U3TR/xqks+dehgSe+1eTzHbEH7jZnEG/8TUT6173 jpKuyZ0MhqzMDByMciKKbL4FLRMjdmUHPZhx9R6mEGsTCBTGLg4BWAiRjs4GPqc5X5cCDIwuK+y rf3DoaywuvyoYvGL3/mzWm9/ye6KfNoebRrbKNabmsm9622qkcw5RrZrHw8ERE2qCn7/zM3he4f 70gM+DPdn+HPPauW9IrF9TeHHc3918923N+SoxesyevJobGpmfRyRc+DevuwXa+IWVyqdW/wurr outez1RRN+12prlvVbn6T1/73x76LM7FAhxR0djBwWx62/mhjwVvyP8DjusPhDa9MBNVGxT7nLb ewfZq3m35bu/Sb4zuQDLMuP3L6TrbzjbQdXwyPetRIHH7cm/y+3e1ayt2zp2fWxTKdO7asufr+k YEtdwCpBpY+GroWx5RdquXYKH8hxC5ZdZadvt+/T+Zs3AA== X-Developer-Key: i=dmitry.baryshkov@linaro.org; a=openpgp; fpr=8F88381DD5C873E4AE487DA5199BF1243632046A X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240627_074453_795568_9BCFC075 X-CRM114-Status: GOOD ( 21.58 ) 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 Extract common functions to handle command sending and to handle events from UCSI. This ensures that all UCSI glue drivers handle the ACKs in the same way. The CCG driver used DEV_CMD_PENDING both for internal firmware-related commands and for UCSI control handling. Leave the former use case intact. Tested-by: Heikki Krogerus Reviewed-by: Heikki Krogerus Signed-off-by: Dmitry Baryshkov --- drivers/usb/typec/ucsi/ucsi.c | 43 +++++++++++++++++++++++++ drivers/usb/typec/ucsi/ucsi.h | 7 +++++ drivers/usb/typec/ucsi/ucsi_acpi.c | 56 +++++---------------------------- drivers/usb/typec/ucsi/ucsi_ccg.c | 21 ++----------- drivers/usb/typec/ucsi/ucsi_glink.c | 47 ++------------------------- drivers/usb/typec/ucsi/ucsi_stm32g0.c | 44 ++------------------------ drivers/usb/typec/ucsi/ucsi_yoga_c630.c | 52 ++---------------------------- 7 files changed, 67 insertions(+), 203 deletions(-) diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c index 2d87fe277c62..25d2ee5ee8bb 100644 --- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -36,6 +36,48 @@ */ #define UCSI_SWAP_TIMEOUT_MS 5000 +void ucsi_notify_common(struct ucsi *ucsi, u32 cci) +{ + if (UCSI_CCI_CONNECTOR(cci)) + ucsi_connector_change(ucsi, UCSI_CCI_CONNECTOR(cci)); + + if (cci & UCSI_CCI_ACK_COMPLETE && + test_bit(ACK_PENDING, &ucsi->flags)) + complete(&ucsi->complete); + + if (cci & UCSI_CCI_COMMAND_COMPLETE && + test_bit(COMMAND_PENDING, &ucsi->flags)) + complete(&ucsi->complete); +} +EXPORT_SYMBOL_GPL(ucsi_notify_common); + +int ucsi_sync_control_common(struct ucsi *ucsi, u64 command) +{ + bool ack = UCSI_COMMAND(command) == UCSI_ACK_CC_CI; + int ret; + + if (ack) + set_bit(ACK_PENDING, &ucsi->flags); + else + set_bit(COMMAND_PENDING, &ucsi->flags); + + ret = ucsi->ops->async_control(ucsi, command); + if (ret) + goto out_clear_bit; + + if (!wait_for_completion_timeout(&ucsi->complete, 5 * HZ)) + ret = -ETIMEDOUT; + +out_clear_bit: + if (ack) + clear_bit(ACK_PENDING, &ucsi->flags); + else + clear_bit(COMMAND_PENDING, &ucsi->flags); + + return ret; +} +EXPORT_SYMBOL_GPL(ucsi_sync_control_common); + static int ucsi_acknowledge(struct ucsi *ucsi, bool conn_ack) { u64 ctrl; @@ -1919,6 +1961,7 @@ struct ucsi *ucsi_create(struct device *dev, const struct ucsi_operations *ops) INIT_WORK(&ucsi->resume_work, ucsi_resume_work); INIT_DELAYED_WORK(&ucsi->work, ucsi_init_work); mutex_init(&ucsi->ppm_lock); + init_completion(&ucsi->complete); ucsi->dev = dev; ucsi->ops = ops; diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h index 2560e144e158..57129f3c0814 100644 --- a/drivers/usb/typec/ucsi/ucsi.h +++ b/drivers/usb/typec/ucsi/ucsi.h @@ -4,6 +4,7 @@ #define __DRIVER_USB_TYPEC_UCSI_H #include +#include #include #include #include @@ -425,6 +426,9 @@ struct ucsi { /* PPM communication flags */ unsigned long flags; #define EVENT_PENDING 0 +#define COMMAND_PENDING 1 +#define ACK_PENDING 2 + struct completion complete; unsigned long quirks; #define UCSI_NO_PARTNER_PDOS BIT(0) /* Don't read partner's PDOs */ @@ -489,6 +493,9 @@ int ucsi_send_command(struct ucsi *ucsi, u64 command, void ucsi_altmode_update_active(struct ucsi_connector *con); int ucsi_resume(struct ucsi *ucsi); +void ucsi_notify_common(struct ucsi *ucsi, u32 cci); +int ucsi_sync_control_common(struct ucsi *ucsi, u64 command); + #if IS_ENABLED(CONFIG_POWER_SUPPLY) int ucsi_register_port_psy(struct ucsi_connector *con); void ucsi_unregister_port_psy(struct ucsi_connector *con); diff --git a/drivers/usb/typec/ucsi/ucsi_acpi.c b/drivers/usb/typec/ucsi/ucsi_acpi.c index 3660dc3e6d32..7a5dff8d9cc6 100644 --- a/drivers/usb/typec/ucsi/ucsi_acpi.c +++ b/drivers/usb/typec/ucsi/ucsi_acpi.c @@ -21,11 +21,7 @@ struct ucsi_acpi { struct device *dev; struct ucsi *ucsi; void *base; - struct completion complete; - unsigned long flags; -#define UCSI_ACPI_COMMAND_PENDING 1 -#define UCSI_ACPI_ACK_PENDING 2 -#define UCSI_ACPI_CHECK_BOGUS_EVENT 3 + bool check_bogus_event; guid_t guid; u64 cmd; }; @@ -98,38 +94,11 @@ static int ucsi_acpi_async_control(struct ucsi *ucsi, u64 command) return ucsi_acpi_dsm(ua, UCSI_DSM_FUNC_WRITE); } -static int ucsi_acpi_sync_control(struct ucsi *ucsi, u64 command) -{ - struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); - bool ack = UCSI_COMMAND(command) == UCSI_ACK_CC_CI; - int ret; - - if (ack) - set_bit(UCSI_ACPI_ACK_PENDING, &ua->flags); - else - set_bit(UCSI_ACPI_COMMAND_PENDING, &ua->flags); - - ret = ucsi_acpi_async_control(ucsi, command); - if (ret) - goto out_clear_bit; - - if (!wait_for_completion_timeout(&ua->complete, 5 * HZ)) - ret = -ETIMEDOUT; - -out_clear_bit: - if (ack) - clear_bit(UCSI_ACPI_ACK_PENDING, &ua->flags); - else - clear_bit(UCSI_ACPI_COMMAND_PENDING, &ua->flags); - - return ret; -} - static const struct ucsi_operations ucsi_acpi_ops = { .read_version = ucsi_acpi_read_version, .read_cci = ucsi_acpi_read_cci, .read_message_in = ucsi_acpi_read_message_in, - .sync_control = ucsi_acpi_sync_control, + .sync_control = ucsi_sync_control_common, .async_control = ucsi_acpi_async_control }; @@ -165,7 +134,7 @@ static const struct ucsi_operations ucsi_zenbook_ops = { .read_version = ucsi_acpi_read_version, .read_cci = ucsi_zenbook_read_cci, .read_message_in = ucsi_zenbook_read_message_in, - .sync_control = ucsi_acpi_sync_control, + .sync_control = ucsi_sync_control_common, .async_control = ucsi_acpi_async_control }; @@ -182,14 +151,14 @@ static int ucsi_gram_read_message_in(struct ucsi *ucsi, void *val, size_t val_le return ret; if (UCSI_COMMAND(ua->cmd) == UCSI_GET_CONNECTOR_STATUS && - test_bit(UCSI_ACPI_CHECK_BOGUS_EVENT, &ua->flags)) { + ua->check_bogus_event) { status = (struct ucsi_connector_status *)val; /* Clear the bogus change */ if (status->change == bogus_change) status->change = 0; - clear_bit(UCSI_ACPI_CHECK_BOGUS_EVENT, &ua->flags); + ua->check_bogus_event = false; } return ret; @@ -200,14 +169,14 @@ static int ucsi_gram_sync_control(struct ucsi *ucsi, u64 command) struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); int ret; - ret = ucsi_acpi_sync_control(ucsi, command); + ret = ucsi_sync_control_common(ucsi, command); if (ret < 0) return ret; if (UCSI_COMMAND(ua->cmd) == UCSI_GET_PDOS && ua->cmd & UCSI_GET_PDOS_PARTNER_PDO(1) && ua->cmd & UCSI_GET_PDOS_SRC_PDOS) - set_bit(UCSI_ACPI_CHECK_BOGUS_EVENT, &ua->flags); + ua->check_bogus_event = true; return ret; } @@ -249,15 +218,7 @@ static void ucsi_acpi_notify(acpi_handle handle, u32 event, void *data) if (ret) return; - if (UCSI_CCI_CONNECTOR(cci)) - ucsi_connector_change(ua->ucsi, UCSI_CCI_CONNECTOR(cci)); - - if (cci & UCSI_CCI_ACK_COMPLETE && - test_bit(UCSI_ACPI_ACK_PENDING, &ua->flags)) - complete(&ua->complete); - if (cci & UCSI_CCI_COMMAND_COMPLETE && - test_bit(UCSI_ACPI_COMMAND_PENDING, &ua->flags)) - complete(&ua->complete); + ucsi_notify_common(ua->ucsi, cci); } static int ucsi_acpi_probe(struct platform_device *pdev) @@ -291,7 +252,6 @@ static int ucsi_acpi_probe(struct platform_device *pdev) if (ret) return ret; - init_completion(&ua->complete); ua->dev = &pdev->dev; id = dmi_first_match(ucsi_acpi_quirks); diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c index 6ccc394f268e..ba4db2310a05 100644 --- a/drivers/usb/typec/ucsi/ucsi_ccg.c +++ b/drivers/usb/typec/ucsi/ucsi_ccg.c @@ -222,8 +222,6 @@ struct ucsi_ccg { u16 fw_build; struct work_struct pm_work; - struct completion complete; - u64 last_cmd_sent; bool has_multiple_dp; struct ucsi_ccg_altmode orig[UCSI_MAX_ALTMODES]; @@ -637,7 +635,6 @@ static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command) mutex_lock(&uc->lock); pm_runtime_get_sync(uc->dev); - set_bit(DEV_CMD_PENDING, &uc->flags); uc->last_cmd_sent = command; @@ -649,15 +646,8 @@ static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command) ucsi_ccg_update_set_new_cam_cmd(uc, con, &command); } - ret = ucsi_ccg_async_control(ucsi, command); - if (ret) - goto err_clear_bit; - - if (!wait_for_completion_timeout(&uc->complete, msecs_to_jiffies(5000))) - ret = -ETIMEDOUT; + ret = ucsi_sync_control_common(ucsi, command); -err_clear_bit: - clear_bit(DEV_CMD_PENDING, &uc->flags); pm_runtime_put_sync(uc->dev); mutex_unlock(&uc->lock); @@ -694,9 +684,6 @@ static irqreturn_t ccg_irq_handler(int irq, void *data) if (ret) goto err_clear_irq; - if (UCSI_CCI_CONNECTOR(cci)) - ucsi_connector_change(uc->ucsi, UCSI_CCI_CONNECTOR(cci)); - /* * As per CCGx UCSI interface guide, copy CCI and MESSAGE_IN * to the OpRegion before clear the UCSI interrupt @@ -708,9 +695,8 @@ static irqreturn_t ccg_irq_handler(int irq, void *data) err_clear_irq: ccg_write(uc, CCGX_RAB_INTR_REG, &intr_reg, sizeof(intr_reg)); - if (!ret && test_bit(DEV_CMD_PENDING, &uc->flags) && - cci & (UCSI_CCI_ACK_COMPLETE | UCSI_CCI_COMMAND_COMPLETE)) - complete(&uc->complete); + if (!ret) + ucsi_notify_common(uc->ucsi, cci); return IRQ_HANDLED; } @@ -1429,7 +1415,6 @@ static int ucsi_ccg_probe(struct i2c_client *client) uc->client = client; uc->irq = client->irq; mutex_init(&uc->lock); - init_completion(&uc->complete); INIT_WORK(&uc->work, ccg_update_firmware); INIT_WORK(&uc->pm_work, ccg_pm_workaround_work); diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c index 56bad054e78f..16c328497e0b 100644 --- a/drivers/usb/typec/ucsi/ucsi_glink.c +++ b/drivers/usb/typec/ucsi/ucsi_glink.c @@ -64,12 +64,8 @@ struct pmic_glink_ucsi { struct ucsi *ucsi; struct completion read_ack; struct completion write_ack; - struct completion sync_ack; - bool sync_pending; struct mutex lock; /* protects concurrent access to PMIC Glink interface */ - int sync_val; - struct work_struct notify_work; struct work_struct register_work; @@ -170,35 +166,6 @@ static int pmic_glink_ucsi_async_control(struct ucsi *__ucsi, u64 command) return ret; } -static int pmic_glink_ucsi_sync_control(struct ucsi *__ucsi, u64 command) -{ - struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(__ucsi); - unsigned long left; - int ret; - - /* TOFIX: Downstream forces recipient to CON when UCSI_GET_ALTERNATE_MODES command */ - - mutex_lock(&ucsi->lock); - ucsi->sync_val = 0; - reinit_completion(&ucsi->sync_ack); - ucsi->sync_pending = true; - ret = pmic_glink_ucsi_locked_write(ucsi, UCSI_CONTROL, &command, sizeof(command)); - mutex_unlock(&ucsi->lock); - - left = wait_for_completion_timeout(&ucsi->sync_ack, 5 * HZ); - if (!left) { - dev_err(ucsi->dev, "timeout waiting for UCSI sync write response\n"); - /* return 0 here and let core UCSI code handle the CCI_BUSY */ - ret = 0; - } else if (ucsi->sync_val) { - dev_err(ucsi->dev, "sync write returned: %d\n", ucsi->sync_val); - } - - ucsi->sync_pending = false; - - return ret; -} - static void pmic_glink_ucsi_update_connector(struct ucsi_connector *con) { struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(con->ucsi); @@ -232,7 +199,7 @@ static const struct ucsi_operations pmic_glink_ucsi_ops = { .read_version = pmic_glink_ucsi_read_version, .read_cci = pmic_glink_ucsi_read_cci, .read_message_in = pmic_glink_ucsi_read_message_in, - .sync_control = pmic_glink_ucsi_sync_control, + .sync_control = ucsi_sync_control_common, .async_control = pmic_glink_ucsi_async_control, .update_connector = pmic_glink_ucsi_update_connector, .connector_status = pmic_glink_ucsi_connector_status, @@ -256,14 +223,12 @@ static void pmic_glink_ucsi_write_ack(struct pmic_glink_ucsi *ucsi, const void * if (resp->ret_code) return; - ucsi->sync_val = resp->ret_code; complete(&ucsi->write_ack); } static void pmic_glink_ucsi_notify(struct work_struct *work) { struct pmic_glink_ucsi *ucsi = container_of(work, struct pmic_glink_ucsi, notify_work); - unsigned int con_num; u32 cci; int ret; @@ -273,14 +238,7 @@ static void pmic_glink_ucsi_notify(struct work_struct *work) return; } - con_num = UCSI_CCI_CONNECTOR(cci); - if (con_num) - ucsi_connector_change(ucsi->ucsi, con_num); - - if (ucsi->sync_pending && - (cci & (UCSI_CCI_ACK_COMPLETE | UCSI_CCI_COMMAND_COMPLETE))) { - complete(&ucsi->sync_ack); - } + ucsi_notify_common(ucsi->ucsi, cci); } static void pmic_glink_ucsi_register(struct work_struct *work) @@ -362,7 +320,6 @@ static int pmic_glink_ucsi_probe(struct auxiliary_device *adev, INIT_WORK(&ucsi->register_work, pmic_glink_ucsi_register); init_completion(&ucsi->read_ack); init_completion(&ucsi->write_ack); - init_completion(&ucsi->sync_ack); mutex_init(&ucsi->lock); ucsi->ucsi = ucsi_create(dev, &pmic_glink_ucsi_ops); diff --git a/drivers/usb/typec/ucsi/ucsi_stm32g0.c b/drivers/usb/typec/ucsi/ucsi_stm32g0.c index 14737ca3724c..d948c3f579e1 100644 --- a/drivers/usb/typec/ucsi/ucsi_stm32g0.c +++ b/drivers/usb/typec/ucsi/ucsi_stm32g0.c @@ -61,11 +61,7 @@ struct ucsi_stm32g0 { struct i2c_client *i2c_bl; bool in_bootloader; u8 bl_version; - struct completion complete; struct device *dev; - unsigned long flags; -#define COMMAND_PENDING 1 -#define ACK_PENDING 2 const char *fw_name; struct ucsi *ucsi; bool suspended; @@ -407,35 +403,6 @@ static int ucsi_stm32g0_async_control(struct ucsi *ucsi, u64 command) return 0; } -static int ucsi_stm32g0_sync_control(struct ucsi *ucsi, u64 command) -{ - struct ucsi_stm32g0 *g0 = ucsi_get_drvdata(ucsi); - bool ack = UCSI_COMMAND(command) == UCSI_ACK_CC_CI; - int ret; - - if (ack) - set_bit(ACK_PENDING, &g0->flags); - else - set_bit(COMMAND_PENDING, &g0->flags); - - ret = ucsi_stm32g0_async_control(ucsi, command); - if (ret) - goto out_clear_bit; - - if (!wait_for_completion_timeout(&g0->complete, msecs_to_jiffies(5000))) - ret = -ETIMEDOUT; - else - return 0; - -out_clear_bit: - if (ack) - clear_bit(ACK_PENDING, &g0->flags); - else - clear_bit(COMMAND_PENDING, &g0->flags); - - return ret; -} - static irqreturn_t ucsi_stm32g0_irq_handler(int irq, void *data) { struct ucsi_stm32g0 *g0 = data; @@ -449,13 +416,7 @@ static irqreturn_t ucsi_stm32g0_irq_handler(int irq, void *data) if (ret) return IRQ_NONE; - if (UCSI_CCI_CONNECTOR(cci)) - ucsi_connector_change(g0->ucsi, UCSI_CCI_CONNECTOR(cci)); - - 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); + ucsi_notify_common(g0->ucsi, cci); return IRQ_HANDLED; } @@ -464,7 +425,7 @@ static const struct ucsi_operations ucsi_stm32g0_ops = { .read_version = ucsi_stm32g0_read_version, .read_cci = ucsi_stm32g0_read_cci, .read_message_in = ucsi_stm32g0_read_message_in, - .sync_control = ucsi_stm32g0_sync_control, + .sync_control = ucsi_sync_control_common, .async_control = ucsi_stm32g0_async_control, }; @@ -665,7 +626,6 @@ static int ucsi_stm32g0_probe(struct i2c_client *client) g0->dev = dev; g0->client = client; - init_completion(&g0->complete); i2c_set_clientdata(client, g0); g0->ucsi = ucsi_create(dev, &ucsi_stm32g0_ops); diff --git a/drivers/usb/typec/ucsi/ucsi_yoga_c630.c b/drivers/usb/typec/ucsi/ucsi_yoga_c630.c index 95a333ad5496..f3a5e24ea84d 100644 --- a/drivers/usb/typec/ucsi/ucsi_yoga_c630.c +++ b/drivers/usb/typec/ucsi/ucsi_yoga_c630.c @@ -20,10 +20,6 @@ struct yoga_c630_ucsi { struct yoga_c630_ec *ec; struct ucsi *ucsi; struct notifier_block nb; - struct completion complete; - unsigned long flags; -#define UCSI_C630_COMMAND_PENDING 0 -#define UCSI_C630_ACK_PENDING 1 u16 version; }; @@ -75,57 +71,14 @@ static int yoga_c630_ucsi_async_control(struct ucsi *ucsi, u64 command) return yoga_c630_ec_ucsi_write(uec->ec, (u8*)&command); } -static int yoga_c630_ucsi_sync_control(struct ucsi *ucsi, u64 command) -{ - struct yoga_c630_ucsi *uec = ucsi_get_drvdata(ucsi); - bool ack = UCSI_COMMAND(command) == UCSI_ACK_CC_CI; - int ret; - - if (ack) - set_bit(UCSI_C630_ACK_PENDING, &uec->flags); - else - set_bit(UCSI_C630_COMMAND_PENDING, &uec->flags); - - reinit_completion(&uec->complete); - - ret = yoga_c630_ucsi_async_control(ucsi, command); - if (ret) - goto out_clear_bit; - - if (!wait_for_completion_timeout(&uec->complete, 5 * HZ)) - ret = -ETIMEDOUT; - -out_clear_bit: - if (ack) - clear_bit(UCSI_C630_ACK_PENDING, &uec->flags); - else - clear_bit(UCSI_C630_COMMAND_PENDING, &uec->flags); - - return ret; -} - const struct ucsi_operations yoga_c630_ucsi_ops = { .read_version = yoga_c630_ucsi_read_version, .read_cci = yoga_c630_ucsi_read_cci, .read_message_in = yoga_c630_ucsi_read_message_in, - .sync_control = yoga_c630_ucsi_sync_control, + .sync_control = ucsi_sync_control_common, .async_control = yoga_c630_ucsi_async_control, }; -static void yoga_c630_ucsi_notify_ucsi(struct yoga_c630_ucsi *uec, u32 cci) -{ - if (UCSI_CCI_CONNECTOR(cci)) - ucsi_connector_change(uec->ucsi, UCSI_CCI_CONNECTOR(cci)); - - if (cci & UCSI_CCI_ACK_COMPLETE && - test_bit(UCSI_C630_ACK_PENDING, &uec->flags)) - complete(&uec->complete); - - if (cci & UCSI_CCI_COMMAND_COMPLETE && - test_bit(UCSI_C630_COMMAND_PENDING, &uec->flags)) - complete(&uec->complete); -} - static int yoga_c630_ucsi_notify(struct notifier_block *nb, unsigned long action, void *data) { @@ -144,7 +97,7 @@ static int yoga_c630_ucsi_notify(struct notifier_block *nb, if (ret) return NOTIFY_DONE; - yoga_c630_ucsi_notify_ucsi(uec, cci); + ucsi_notify_common(uec->ucsi, cci); return NOTIFY_OK; @@ -165,7 +118,6 @@ static int yoga_c630_ucsi_probe(struct auxiliary_device *adev, return -ENOMEM; uec->ec = ec; - init_completion(&uec->complete); uec->nb.notifier_call = yoga_c630_ucsi_notify; uec->ucsi = ucsi_create(&adev->dev, &yoga_c630_ucsi_ops); From patchwork Thu Jun 27 14:44:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13714512 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 4312EC30653 for ; Thu, 27 Jun 2024 14:46:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References :Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=dO9vc3WlwnOOdxIv2wYOfRp/f4HDsDDrITVn2Ghy1d0=; b=nSGD5rhKLfJSaWh0FWdHXsrNme WiEBqz6SFWvDG054jpEj2gm1gZtoUjD6tzfzSRSFpyMwzDo9p5iJILKMtEujyU10Ulqnhhae+Yw1I oHsZeGYk50tfkeC7A+YEUODrXLMB0MJKB2s6O5+gNfVq07yW+6TT21HgXT1S4Tu7ebCfIwdJn8SIh hPf2TgwbAXRhyaijRPQd3DGb4FifQR1zNDgrYDGPRTlFb8TcAnLiErI5knHYmBFcO9XZpnaRJTxBL o+NRCvtPEh1k+qtasB2sxyDG1X/RaPvCIsEQU5pIfjV956LYEuwbCTCF5OAKHqk7TY9UQEgA9x5IC VnpTHfJw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sMqNh-0000000AgqG-3EQr; Thu, 27 Jun 2024 14:45:49 +0000 Received: from mail-lj1-x22b.google.com ([2a00:1450:4864:20::22b]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sMqMo-0000000AgLv-2xgS for linux-arm-kernel@lists.infradead.org; Thu, 27 Jun 2024 14:44:59 +0000 Received: by mail-lj1-x22b.google.com with SMTP id 38308e7fff4ca-2ec17eb4493so110592641fa.2 for ; Thu, 27 Jun 2024 07:44:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1719499489; x=1720104289; darn=lists.infradead.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=dO9vc3WlwnOOdxIv2wYOfRp/f4HDsDDrITVn2Ghy1d0=; b=jHVqHuhoDJ6iRhPTFn2Lzr3OfPodUF4HPgYwnJXb4UB7pOKRkeBtOH66e6c5/azo3B 2+8ZlsFIT8c9Oeu6K0fQ/4q65OYM2W7WUeRnN8fOx6yj/RCf/DNhI7OliN1OaVlACIMV qLRAJZ2b82HMeru5bLlcIVLOZD4EUvISZRUpWd4c4LtfyrZSD7s/HsfFki63t1MTXMTy WplOJOfxuaE1ecbi0cntYUKBirVlm/Yk6YaEW9DKWfqo9A2Q8/sifMRDZLBHnuhNVgKT 3kEoKs4JBjct6+Mo1tcO/LvDlY0Sm2TuhDnP8q9UswAjT8H++CQpbGN12e+0QJ95blCI l4qA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719499489; x=1720104289; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=dO9vc3WlwnOOdxIv2wYOfRp/f4HDsDDrITVn2Ghy1d0=; b=D7We9P4Y66jBCQ4GQBcKcei9KIupfiK+jeY/PkZmkJil5cPj9L9/8hg5w20Nm69rXg ROIB8cvIcANqZXCaQbk+GPMOGzmQCmzUBK+AwdcszRpEZ+N7+rEcK14insfG+IBFtuQ6 apyudWkzezKTHHtcQ9jrsT2b8XhtSQszWRTS+U9T8885yyLjZk+bgVcO6DSiIWha2Vke HJxk6xHaB2MyEPU62tiwejIEVYQXo1m4Zynxh7ipDAUeQTH0Wrz6sA9fhPld+hbqq0UM b1dLt3I4NvjgQkC+3DvkhLFCMZ/HjSZR4V5cOS6Bb7mbADxlnN3+JhQ6HVwgsd7KCVzb AcLA== X-Forwarded-Encrypted: i=1; AJvYcCXTRSh9rHY8AWTlcSheQDEvY42iEvkpnQ4+tvIxiA7/G4w6/yAs6DjaFxyfCC9Ow5bBY/+CGVergGZ8ELbWH5k9HSH1A3eOxmqeb1oUmaehDYdi2t8= X-Gm-Message-State: AOJu0YwdSQFs/+EdHy9hWU2O/Zg8VgbPJm2usfVciOv42QKzWBq+QjtE O+rRqCYUw4mRJioC1eqbgf8VgcxZr0PC2afkwExXrZb7I2u9J16K5r75PlJrpJ8= X-Google-Smtp-Source: AGHT+IH7syasty7HaTDsD5E51KorF8XfnrmM9ehc/fLT067hmE63RvbKOsoAR+lMidxzL11uJ8ieFA== X-Received: by 2002:a2e:a5cb:0:b0:2ee:4a67:3d82 with SMTP id 38308e7fff4ca-2ee4a673edcmr21435651fa.28.1719499489631; Thu, 27 Jun 2024 07:44:49 -0700 (PDT) Received: from umbar.lan ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-2ee4a34447fsm2775911fa.11.2024.06.27.07.44.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Jun 2024 07:44:49 -0700 (PDT) From: Dmitry Baryshkov Date: Thu, 27 Jun 2024 17:44:46 +0300 Subject: [PATCH v4 7/7] usb: typec: ucsi: reorder operations in ucsi_run_command() MIME-Version: 1.0 Message-Id: <20240627-ucsi-rework-interface-v4-7-289ddc6874c7@linaro.org> References: <20240627-ucsi-rework-interface-v4-0-289ddc6874c7@linaro.org> In-Reply-To: <20240627-ucsi-rework-interface-v4-0-289ddc6874c7@linaro.org> To: Heikki Krogerus , Greg Kroah-Hartman , Maxime Coquelin , Alexandre Torgue Cc: Nikita Travkin , Neil Armstrong , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2214; i=dmitry.baryshkov@linaro.org; h=from:subject:message-id; bh=8t+rc0a05n9eyrWDZO2kMieJ1aEfnXGXWDcAD9GfTds=; b=owEBbQGS/pANAwAKAYs8ij4CKSjVAcsmYgBmfXratpXe2Md2H7XXIFiFlNCnAymp1cbi5Lu3s qKILWjJemOJATMEAAEKAB0WIQRMcISVXLJjVvC4lX+LPIo+Aiko1QUCZn162gAKCRCLPIo+Aiko 1Vy9CACQ+eAL9dx+gexu83BB5XxVSv6Vuxl4xliWjn7OFQ5qhxpaKRh9ucFB2OfRdDoDeIVc18T MoqzXZJWA2gqYP1kStZ4QPCA6+0iw8+2UHZd9AsQKWvzcrmtuwKzwy1V462QBHKrujuB1iw/5CR T/5lE2vCu/gucwCPeeSYreoIpc6c27v32N8foNt1wKRy2iNpl5mhJloJqi00fHLWHDVVYTwzdV1 5RKDglkwuPy7nsSYxwg/s/2tRnL8pyw70IotCuYqMpoix5oGImSWc8bxTX73YyyXJ6FCuiDNHPW +4ySKPNRD0Ud8QgBYaG+IbKt41a4Heejgijje2FTFn7iNol4 X-Developer-Key: i=dmitry.baryshkov@linaro.org; a=openpgp; fpr=8F88381DD5C873E4AE487DA5199BF1243632046A X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240627_074454_798001_B9F54600 X-CRM114-Status: GOOD ( 15.57 ) 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 Streamline control stream of ucsi_run_command(). Reorder operations so that there is only one call to ucsi_acknowledge(), making sure that all complete commands are acknowledged. This also makes sure that the command is acknowledged even if reading MESSAGE_IN data returns an error. Tested-by: Heikki Krogerus Reviewed-by: Heikki Krogerus Signed-off-by: Dmitry Baryshkov --- drivers/usb/typec/ucsi/ucsi.c | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c index 25d2ee5ee8bb..dcd3765cc1f5 100644 --- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -95,7 +95,7 @@ static int ucsi_acknowledge(struct ucsi *ucsi, bool conn_ack) static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci, void *data, size_t size, bool conn_ack) { - int ret; + int ret, err; *cci = 0; @@ -120,30 +120,24 @@ static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci, if (!(*cci & UCSI_CCI_COMMAND_COMPLETE)) return -EIO; - if (*cci & UCSI_CCI_NOT_SUPPORTED) { - if (ucsi_acknowledge(ucsi, false) < 0) - dev_err(ucsi->dev, - "ACK of unsupported command failed\n"); - return -EOPNOTSUPP; - } - - if (*cci & UCSI_CCI_ERROR) { - /* Acknowledge the command that failed */ - ret = ucsi_acknowledge(ucsi, false); - return ret ? ret : -EIO; - } + if (*cci & UCSI_CCI_NOT_SUPPORTED) + err = -EOPNOTSUPP; + else if (*cci & UCSI_CCI_ERROR) + err = -EIO; + else + err = 0; - if (data) { - ret = ucsi->ops->read_message_in(ucsi, data, size); - if (ret) - return ret; - } + if (!err && data && UCSI_CCI_LENGTH(*cci)) + err = ucsi->ops->read_message_in(ucsi, data, size); - ret = ucsi_acknowledge(ucsi, conn_ack); + /* + * Don't ACK connection change if there was an error. + */ + ret = ucsi_acknowledge(ucsi, err ? false : conn_ack); if (ret) return ret; - return 0; + return err; } static int ucsi_read_error(struct ucsi *ucsi, u8 connector_num)