Message ID | 1698202408-14608-3-git-send-email-quic_taozha@quicinc.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:ce89:0:b0:403:3b70:6f57 with SMTP id p9csp2332590vqx; Tue, 24 Oct 2023 19:54:24 -0700 (PDT) X-Google-Smtp-Source: AGHT+IH8aM402ubflGDeIHyUQ/RDnpkHasPKGm95lGiw1EI0XCBolAp6yWbGWjDb6aTqjA46rpzT X-Received: by 2002:a81:4955:0:b0:5a7:b53a:3223 with SMTP id w82-20020a814955000000b005a7b53a3223mr18179275ywa.21.1698202463849; Tue, 24 Oct 2023 19:54:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1698202463; cv=none; d=google.com; s=arc-20160816; b=Bz4VGfAvf1rPEAD3P3fdSPCIaKuEksg5Rd18tgmnqETXQHkH3lxf9Z6i+xGm2I60bt NSzD8cxVbMax/T8BahazVl6W4LkCnJqXBMkQCjsp5P6LTrByANvnlo3XM+Pk5PGqE16y eQdrTCR73/milCl9l61Oc+9a9hneYZ5vtGuvzVBbL85u0ryBWVhHFMgo0AZ092dBIxIv h2/ZqX8FWj5RTimQfHidnbVLjBVRQLTk0x/etq92T1C+ByJ3MrciRAz7mo7h1ifSw6U8 Wxr/mXLaQ3+SGwVFh7h/kd+xd0wnGgf+uwhlzWWG3igooSl4EesOvNQbpX8y3yyk4bCw Hjog== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=NIoEyXGPgRWqdqAqVxRbqqexiIwroT81XVZyT5MPmrE=; fh=eSQnxfYZD66NgboVDB7L9mVH46SSiFzLE3y556oFJtg=; b=kAnoZ9/br/NBw24GbHfEoC6rKAb6VqcrCfumxuUkD5+q6sx7krtSZfq6b3dHrKjZNM TtLvZ0d8ymOu016zg9t915LhrAkPmmnsy/yidBa67AqFglkGlfJOX6ofrVnNW+89Sw0W BAP5YlA6bC/Os+fgTOaxmJiUrLeEDw0WTYraIb1JFZ0v2N37t2yTU1dzCvPze57rU8Wx 8gW6wbUeNTLb4wuBZ8+X8dPy5nrqQJzfOlhiZ9Lwz8tC7axFnbj27dQ9UDRlQ7eyKShP MxeaOMAY0FSDqG8iMqSse/rgszRwsJmAfCmIgpPDVHdEYNKNlcxR6FBjdQkprnG7F8gF ZYeg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=YFqlLnio; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=quicinc.com Received: from snail.vger.email (snail.vger.email. [23.128.96.37]) by mx.google.com with ESMTPS id e82-20020a816955000000b0058d37d41f1dsi9491056ywc.16.2023.10.24.19.54.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Oct 2023 19:54:23 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) client-ip=23.128.96.37; Authentication-Results: mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=YFqlLnio; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=quicinc.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id 61900802581B; Tue, 24 Oct 2023 19:54:22 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232262AbjJYCyT (ORCPT <rfc822;aposhian.dev@gmail.com> + 26 others); Tue, 24 Oct 2023 22:54:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35992 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232234AbjJYCyR (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Tue, 24 Oct 2023 22:54:17 -0400 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BC6E310D1; Tue, 24 Oct 2023 19:54:14 -0700 (PDT) Received: from pps.filterd (m0279871.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 39P2s3R5023036; Wed, 25 Oct 2023 02:54:03 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=qcppdkim1; bh=NIoEyXGPgRWqdqAqVxRbqqexiIwroT81XVZyT5MPmrE=; b=YFqlLnio3fqES1RMET2M8+vJ4W4i2uiAqY1eNHSm/fCjhLmkBEQQNcvnuqzSxDeBdyrl giQAbbOczxecUpanPej8W/UR63p7T5w05Guebggmmh6t7RDHKXlLHNdpVXNfi6HML8Zb t4qKHsDeS810PRcv/RDGgCxhVCYrKDRP0FAEQpDu/50camXtoFaSEkZNJ7QfOjF5X8Hx A4u79mt1yAEaK8bGCcm60PQ6pkZbFWPHpNLbgJbW/GvvtPOa41+z4vNjQuA9gjdT/Kww Wp/S1RR5TBNt6ywlaHpaTvNTRRgQyCtPRK1Jbawo6Dch9TqNjb97+zToic55DpvXO3rU 8Q== Received: from nalasppmta03.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3txpj5gc69-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 25 Oct 2023 02:54:02 +0000 Received: from nalasex01c.na.qualcomm.com (nalasex01c.na.qualcomm.com [10.47.97.35]) by NALASPPMTA03.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 39P2s1QL013295 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 25 Oct 2023 02:54:01 GMT Received: from taozha-gv.qualcomm.com (10.80.80.8) by nalasex01c.na.qualcomm.com (10.47.97.35) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.39; Tue, 24 Oct 2023 19:53:56 -0700 From: Tao Zhang <quic_taozha@quicinc.com> To: Mathieu Poirier <mathieu.poirier@linaro.org>, Suzuki K Poulose <suzuki.poulose@arm.com>, Alexander Shishkin <alexander.shishkin@linux.intel.com>, Konrad Dybcio <konradybcio@gmail.com>, Mike Leach <mike.leach@linaro.org>, Rob Herring <robh+dt@kernel.org>, Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org> CC: Tao Zhang <quic_taozha@quicinc.com>, Jinlong Mao <quic_jinlmao@quicinc.com>, Leo Yan <leo.yan@linaro.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, <coresight@lists.linaro.org>, <linux-arm-kernel@lists.infradead.org>, <linux-kernel@vger.kernel.org>, <devicetree@vger.kernel.org>, Tingwei Zhang <quic_tingweiz@quicinc.com>, Yuanfang Zhang <quic_yuanfang@quicinc.com>, Trilok Soni <quic_tsoni@quicinc.com>, Song Chai <quic_songchai@quicinc.com>, <linux-arm-msm@vger.kernel.org>, <andersson@kernel.org> Subject: [PATCH v2 2/8] coresight-tpda: Add support to configure CMB element Date: Wed, 25 Oct 2023 10:53:22 +0800 Message-ID: <1698202408-14608-3-git-send-email-quic_taozha@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1698202408-14608-1-git-send-email-quic_taozha@quicinc.com> References: <1698202408-14608-1-git-send-email-quic_taozha@quicinc.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01c.na.qualcomm.com (10.47.97.35) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: LMxAxuN4XojduIapgTRPssScf3VsMpqm X-Proofpoint-GUID: LMxAxuN4XojduIapgTRPssScf3VsMpqm X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.980,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-10-25_01,2023-10-24_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 malwarescore=0 adultscore=0 phishscore=0 clxscore=1015 suspectscore=0 bulkscore=0 priorityscore=1501 impostorscore=0 mlxlogscore=814 spamscore=0 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2310170001 definitions=main-2310250022 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Tue, 24 Oct 2023 19:54:22 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1780694347153963233 X-GMAIL-MSGID: 1780694347153963233 |
Series |
[v2,1/8] dt-bindings: arm: Add support for CMB element size
|
|
Commit Message
Tao Zhang
Oct. 25, 2023, 2:53 a.m. UTC
Read the CMB element size from the device tree. Set the register bit that controls the CMB element size of the corresponding port. Signed-off-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Mao Jinlong <quic_jinlmao@quicinc.com> --- drivers/hwtracing/coresight/coresight-tpda.c | 108 ++++++++++++++++----------- drivers/hwtracing/coresight/coresight-tpda.h | 6 ++ 2 files changed, 69 insertions(+), 45 deletions(-)
Comments
On 25/10/2023 03:53, Tao Zhang wrote: > Read the CMB element size from the device tree. Set the register > bit that controls the CMB element size of the corresponding port. > > Signed-off-by: Tao Zhang <quic_taozha@quicinc.com> > Signed-off-by: Mao Jinlong <quic_jinlmao@quicinc.com> > --- > drivers/hwtracing/coresight/coresight-tpda.c | 108 ++++++++++++++++----------- > drivers/hwtracing/coresight/coresight-tpda.h | 6 ++ > 2 files changed, 69 insertions(+), 45 deletions(-) > > diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c > index 5f82737..3101d2a 100644 > --- a/drivers/hwtracing/coresight/coresight-tpda.c > +++ b/drivers/hwtracing/coresight/coresight-tpda.c > @@ -28,24 +28,54 @@ static bool coresight_device_is_tpdm(struct coresight_device *csdev) > CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM); > } > > +static void tpdm_clear_element_size(struct coresight_device *csdev) > +{ > + struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); > + > + if (drvdata->dsb_esize) > + drvdata->dsb_esize = 0; > + if (drvdata->cmb_esize) > + drvdata->cmb_esize = 0; > +} > + > +static void tpda_set_element_size(struct tpda_drvdata *drvdata, u32 *val) > +{ > + > + if (drvdata->dsb_esize == 64) > + *val |= TPDA_Pn_CR_DSBSIZE; > + else if (drvdata->dsb_esize == 32) > + *val &= ~TPDA_Pn_CR_DSBSIZE; > + > + if (drvdata->cmb_esize == 64) > + *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x2); > + else if (drvdata->cmb_esize == 32) > + *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x1); > + else if (drvdata->cmb_esize == 8) > + *val &= ~TPDA_Pn_CR_CMBSIZE; > +} > + > /* > * Read the DSB element size from the TPDM device > * Returns > * The dsb element size read from the devicetree if available. Hi Tao, I think the function description and the return value description above need updating now. > * 0 - Otherwise, with a warning once. > */ > -static int tpdm_read_dsb_element_size(struct coresight_device *csdev) > +static int tpdm_read_element_size(struct tpda_drvdata *drvdata, > + struct coresight_device *csdev) > { > - int rc = 0; > - u8 size = 0; > - > - rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent), > - "qcom,dsb-element-size", &size); > + int rc = -EEXIST; > + > + if (!fwnode_property_read_u8(dev_fwnode(csdev->dev.parent), > + "qcom,dsb-element-size", &drvdata->dsb_esize)) > + rc &= 0; Is &= 0 significant? Why not = 0? > + if (!fwnode_property_read_u8(dev_fwnode(csdev->dev.parent), > + "qcom,cmb-element-size", &drvdata->cmb_esize)) > + rc &= 0; > if (rc) > dev_warn_once(&csdev->dev, > - "Failed to read TPDM DSB Element size: %d\n", rc); > + "Failed to read TPDM Element size: %d\n", rc); > > - return size; > + return rc; > } > > /* > @@ -56,13 +86,17 @@ static int tpdm_read_dsb_element_size(struct coresight_device *csdev) > * Parameter "inport" is used to pass in the input port number > * of TPDA, and it is set to -1 in the recursize call. > */ > -static int tpda_get_element_size(struct coresight_device *csdev, > +static int tpda_get_element_size(struct tpda_drvdata *drvdata, > + struct coresight_device *csdev, > int inport) > { > - int dsb_size = -ENOENT; > - int i, size; > + int rc = -ENOENT; > + int i; > struct coresight_device *in; > > + if (inport > 0) > + tpdm_clear_element_size(csdev); > + > for (i = 0; i < csdev->pdata->nr_inconns; i++) { > in = csdev->pdata->in_conns[i]->src_dev; > if (!in) > @@ -74,25 +108,20 @@ static int tpda_get_element_size(struct coresight_device *csdev, > continue; > > if (coresight_device_is_tpdm(in)) { > - size = tpdm_read_dsb_element_size(in); > + if (rc) > + rc = tpdm_read_element_size(drvdata, in); > + else > + return -EINVAL; This is quite hard to follow, is checking rc here before calling tpdm_read_element_size() some kind of way of only calling it once? rc isn't actually a return value at this point, it's just default initialised to -ENOENT. Then it's not clear why the else condition returns an error? > } else { > /* Recurse down the path */ > - size = tpda_get_element_size(in, -1); > - } > - > - if (size < 0) > - return size; > - > - if (dsb_size < 0) { > - /* Found a size, save it. */ > - dsb_size = size; > - } else { > - /* Found duplicate TPDMs */ > - return -EEXIST; > + rc = tpda_get_element_size(drvdata, in, -1); And then why it's assigned here but not checked for an error in this case? Maybe some comments explaining the flow would help. Or to me it seems like a second variable to track the thing that's actually intended could be used as well. Like "bool found_element" or something, rather than re-using rc to also track another thing. > } > } > > - return dsb_size; > + if ((drvdata->dsb_esize) || (drvdata->cmb_esize)) > + rc = 0; > + > + return rc; > } > > /* Settings pre enabling port control register */ > @@ -109,7 +138,7 @@ static void tpda_enable_pre_port(struct tpda_drvdata *drvdata) > static int tpda_enable_port(struct tpda_drvdata *drvdata, int port) > { > u32 val; > - int size; > + int rc; > > val = readl_relaxed(drvdata->base + TPDA_Pn_CR(port)); > /* > @@ -117,29 +146,18 @@ static int tpda_enable_port(struct tpda_drvdata *drvdata, int port) > * Set the bit to 0 if the size is 32 > * Set the bit to 1 if the size is 64 > */ > - size = tpda_get_element_size(drvdata->csdev, port); > - switch (size) { > - case 32: > - val &= ~TPDA_Pn_CR_DSBSIZE; > - break; > - case 64: > - val |= TPDA_Pn_CR_DSBSIZE; > - break; > - case 0: > - return -EEXIST; > - case -EEXIST: > + rc = tpda_get_element_size(drvdata, drvdata->csdev, port); > + if (!rc) { > + tpda_set_element_size(drvdata, &val); > + /* Enable the port */ > + val |= TPDA_Pn_CR_ENA; > + writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port)); > + } else if (rc == -EINVAL) { > dev_warn_once(&drvdata->csdev->dev, > "Detected multiple TPDMs on port %d", -EEXIST); tpdm_read_element_size() can return EEXIST, but then it gets changed back to EINVAL in tpda_get_element_size() without caring about the specific code, before finally being changed back to EEXIST for the warning here. Can it just be propagated as the original value? Or use EINVAL or EEXIST all the way through. That would probably be easier to follow. And then also a comment about why the other possible error values don't result in a warning. Thanks James > - return -EEXIST; > - default: > - return -EINVAL; > } > > - /* Enable the port */ > - val |= TPDA_Pn_CR_ENA; > - writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port)); > - > - return 0; > + return rc; > } > > static int __tpda_enable(struct tpda_drvdata *drvdata, int port) > diff --git a/drivers/hwtracing/coresight/coresight-tpda.h b/drivers/hwtracing/coresight/coresight-tpda.h > index b3b38fd..29164fd 100644 > --- a/drivers/hwtracing/coresight/coresight-tpda.h > +++ b/drivers/hwtracing/coresight/coresight-tpda.h > @@ -10,6 +10,8 @@ > #define TPDA_Pn_CR(n) (0x004 + (n * 4)) > /* Aggregator port enable bit */ > #define TPDA_Pn_CR_ENA BIT(0) > +/* Aggregator port CMB data set element size bit */ > +#define TPDA_Pn_CR_CMBSIZE GENMASK(7, 6) > /* Aggregator port DSB data set element size bit */ > #define TPDA_Pn_CR_DSBSIZE BIT(8) > > @@ -25,6 +27,8 @@ > * @csdev: component vitals needed by the framework. > * @spinlock: lock for the drvdata value. > * @enable: enable status of the component. > + * @dsb_esize Record the DSB element size. > + * @cmb_esize Record the CMB element size. > */ > struct tpda_drvdata { > void __iomem *base; > @@ -32,6 +36,8 @@ struct tpda_drvdata { > struct coresight_device *csdev; > spinlock_t spinlock; > u8 atid; > + u8 dsb_esize; > + u8 cmb_esize; > }; > > #endif /* _CORESIGHT_CORESIGHT_TPDA_H */
On 01/11/2023 08:53, Tao Zhang wrote: > > On 10/30/2023 7:11 PM, James Clark wrote: >> >> On 25/10/2023 03:53, Tao Zhang wrote: >>> Read the CMB element size from the device tree. Set the register >>> bit that controls the CMB element size of the corresponding port. >>> >>> Signed-off-by: Tao Zhang<quic_taozha@quicinc.com> >>> Signed-off-by: Mao Jinlong<quic_jinlmao@quicinc.com> >>> --- >>> drivers/hwtracing/coresight/coresight-tpda.c | 108 >>> ++++++++++++++++----------- >>> drivers/hwtracing/coresight/coresight-tpda.h | 6 ++ >>> 2 files changed, 69 insertions(+), 45 deletions(-) >>> >>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.c >>> b/drivers/hwtracing/coresight/coresight-tpda.c >>> index 5f82737..3101d2a 100644 >>> --- a/drivers/hwtracing/coresight/coresight-tpda.c >>> +++ b/drivers/hwtracing/coresight/coresight-tpda.c >>> @@ -28,24 +28,54 @@ static bool coresight_device_is_tpdm(struct >>> coresight_device *csdev) >>> CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM); >>> } >>> +static void tpdm_clear_element_size(struct coresight_device *csdev) >>> +{ >>> + struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); >>> + >>> + if (drvdata->dsb_esize) >>> + drvdata->dsb_esize = 0; >>> + if (drvdata->cmb_esize) >>> + drvdata->cmb_esize = 0; The ifs don't do anything here, it's just the same as always setting to 0. >>> +} >>> + >>> +static void tpda_set_element_size(struct tpda_drvdata *drvdata, u32 >>> *val) >>> +{ >>> + >>> + if (drvdata->dsb_esize == 64) >>> + *val |= TPDA_Pn_CR_DSBSIZE; >>> + else if (drvdata->dsb_esize == 32) >>> + *val &= ~TPDA_Pn_CR_DSBSIZE; >>> + >>> + if (drvdata->cmb_esize == 64) >>> + *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x2); >>> + else if (drvdata->cmb_esize == 32) >>> + *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x1); >>> + else if (drvdata->cmb_esize == 8) >>> + *val &= ~TPDA_Pn_CR_CMBSIZE; >>> +} >>> + >>> /* >>> * Read the DSB element size from the TPDM device >>> * Returns >>> * The dsb element size read from the devicetree if available. >> Hi Tao, >> >> I think the function description and the return value description above >> need updating now. > I will update this in the next patch series. >> >>> * 0 - Otherwise, with a warning once. >>> */ >>> -static int tpdm_read_dsb_element_size(struct coresight_device *csdev) >>> +static int tpdm_read_element_size(struct tpda_drvdata *drvdata, >>> + struct coresight_device *csdev) >>> { >>> - int rc = 0; >>> - u8 size = 0; >>> - >>> - rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent), >>> - "qcom,dsb-element-size", &size); >>> + int rc = -EEXIST; >>> + >>> + if (!fwnode_property_read_u8(dev_fwnode(csdev->dev.parent), >>> + "qcom,dsb-element-size", &drvdata->dsb_esize)) >>> + rc &= 0; >> Is &= 0 significant? Why not = 0? > I will update this in the next patch series. >> >>> + if (!fwnode_property_read_u8(dev_fwnode(csdev->dev.parent), >>> + "qcom,cmb-element-size", &drvdata->cmb_esize)) >>> + rc &= 0; >>> if (rc) >>> dev_warn_once(&csdev->dev, >>> - "Failed to read TPDM DSB Element size: %d\n", rc); >>> + "Failed to read TPDM Element size: %d\n", rc); >>> - return size; >>> + return rc; >>> } >>> /* >>> @@ -56,13 +86,17 @@ static int tpdm_read_dsb_element_size(struct >>> coresight_device *csdev) >>> * Parameter "inport" is used to pass in the input port number >>> * of TPDA, and it is set to -1 in the recursize call. >>> */ >>> -static int tpda_get_element_size(struct coresight_device *csdev, >>> +static int tpda_get_element_size(struct tpda_drvdata *drvdata, >>> + struct coresight_device *csdev, >>> int inport) >>> { >>> - int dsb_size = -ENOENT; >>> - int i, size; >>> + int rc = -ENOENT; >>> + int i; >>> struct coresight_device *in; >>> + if (inport > 0) >>> + tpdm_clear_element_size(csdev); >>> + >>> for (i = 0; i < csdev->pdata->nr_inconns; i++) { >>> in = csdev->pdata->in_conns[i]->src_dev; >>> if (!in) >>> @@ -74,25 +108,20 @@ static int tpda_get_element_size(struct >>> coresight_device *csdev, >>> continue; >>> if (coresight_device_is_tpdm(in)) { >>> - size = tpdm_read_dsb_element_size(in); >>> + if (rc) >>> + rc = tpdm_read_element_size(drvdata, in); >>> + else >>> + return -EINVAL; >> This is quite hard to follow, is checking rc here before calling >> tpdm_read_element_size() some kind of way of only calling it once? > > Yes, there can only be one TPDM on one input port of TPDA. If > "tpdm_read_element_size" is called > > twice, it means that two TPDMs are found on one input port of TPDA. > >> rc isn't actually a return value at this point, it's just default >> initialised to -ENOENT. > > In this loop, "tpdm_read_element_size" will be called for the first time > TPDM found. If rc equals to > > 0, it means that at lease one TPDM has been found on the input port. > Does it make sense? > >> Then it's not clear why the else condition returns an error? > The same as the above. >> >>> } else { >>> /* Recurse down the path */ >>> - size = tpda_get_element_size(in, -1); >>> - } >>> - >>> - if (size < 0) >>> - return size; >>> - >>> - if (dsb_size < 0) { >>> - /* Found a size, save it. */ >>> - dsb_size = size; >>> - } else { >>> - /* Found duplicate TPDMs */ >>> - return -EEXIST; >>> + rc = tpda_get_element_size(drvdata, in, -1); >> And then why it's assigned here but not checked for an error in this >> case? > > |Remote ETM| |TPDM| > > | branch0 | branch1 > > -------------------------- > > funnel1 > > --------------------------- > > | input port 1 > > ----------------------------- > > TPDA1 > > ----------------------------- > > The branches on some TPDA's input ports may not have TPDM. For example, > branch 0 doesn't has a > > TPDM connected, tpda_get_element_size will not return 0 here. This is a > normal situation. We need to > > continue to find TPDM on branch1 through recursion. > >> >> Maybe some comments explaining the flow would help. Or to me it seems >> like a second variable to track the thing that's actually intended could >> be used as well. Like "bool found_element" or something, rather than >> re-using rc to also track another thing. > > Do you prefer to use "static bool found_element" to mark if we already > have read an element size in > > the recursion function? > You could add a static, or you could use whether a set dsb or cmb size exists to mark that one was found, which I think is already partially done. My confusion comes from the fact that instead of just a recursive search, the function doesn't stop at the first found one, it continues to sanity check that there is only one connected across all ports. And instead of just checking the error condition at the very end, it does it mid recursion, relying on the rc value from a previous iteration. IMO the following is a simplification because it always returns at the first error found, and checks the final condition outside of the recursive function. But you could probably leave it as you have but with some comments explaining why: diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c index 3101d2a0671d..00b7607d36be 100644 --- a/drivers/hwtracing/coresight/coresight-tpda.c +++ b/drivers/hwtracing/coresight/coresight-tpda.c @@ -90,13 +90,10 @@ static int tpda_get_element_size(struct tpda_drvdata *drvdata, struct coresight_device *csdev, int inport) { - int rc = -ENOENT; + int rc = 0; int i; struct coresight_device *in; - if (inport > 0) - tpdm_clear_element_size(csdev); - for (i = 0; i < csdev->pdata->nr_inconns; i++) { in = csdev->pdata->in_conns[i]->src_dev; if (!in) @@ -108,19 +105,23 @@ static int tpda_get_element_size(struct tpda_drvdata *drvdata, continue; if (coresight_device_is_tpdm(in)) { - if (rc) - rc = tpdm_read_element_size(drvdata, in); - else + if ((drvdata->dsb_esize) || (drvdata->cmb_esize)) { + /* Error if already previously found and initialised one */ + dev_warn_once(&drvdata->csdev->dev, + "Detected multiple TPDMs on port %d", -EEXIST); return -EINVAL; + } + rc = tpdm_read_element_size(drvdata, in); + if (rc) + return rc; } else { /* Recurse down the path */ rc = tpda_get_element_size(drvdata, in, -1); + if (rc) + return rc; } } - if ((drvdata->dsb_esize) || (drvdata->cmb_esize)) - rc = 0; - return rc; } @@ -146,15 +147,17 @@ static int tpda_enable_port(struct tpda_drvdata *drvdata, int port) * Set the bit to 0 if the size is 32 * Set the bit to 1 if the size is 64 */ + tpdm_clear_element_size(drvdata->csdev); rc = tpda_get_element_size(drvdata, drvdata->csdev, port); - if (!rc) { + if (!rc && ((drvdata->dsb_esize) || (drvdata->cmb_esize))) + { tpda_set_element_size(drvdata, &val); /* Enable the port */ val |= TPDA_Pn_CR_ENA; writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port)); - } else if (rc == -EINVAL) { - dev_warn_once(&drvdata->csdev->dev, - "Detected multiple TPDMs on port %d", -EEXIST); + } else { + dev_warn_once(&drvdata->csdev->dev, "Didn't find TPDM elem size"); + rc = -EINVAL; } return rc;
On 11/1/2023 7:36 PM, James Clark wrote: > > > On 01/11/2023 08:53, Tao Zhang wrote: >> >> On 10/30/2023 7:11 PM, James Clark wrote: >>> >>> On 25/10/2023 03:53, Tao Zhang wrote: >>>> Read the CMB element size from the device tree. Set the register >>>> bit that controls the CMB element size of the corresponding port. >>>> >>>> Signed-off-by: Tao Zhang<quic_taozha@quicinc.com> >>>> Signed-off-by: Mao Jinlong<quic_jinlmao@quicinc.com> >>>> --- >>>> drivers/hwtracing/coresight/coresight-tpda.c | 108 >>>> ++++++++++++++++----------- >>>> drivers/hwtracing/coresight/coresight-tpda.h | 6 ++ >>>> 2 files changed, 69 insertions(+), 45 deletions(-) >>>> >>>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.c >>>> b/drivers/hwtracing/coresight/coresight-tpda.c >>>> index 5f82737..3101d2a 100644 >>>> --- a/drivers/hwtracing/coresight/coresight-tpda.c >>>> +++ b/drivers/hwtracing/coresight/coresight-tpda.c >>>> @@ -28,24 +28,54 @@ static bool coresight_device_is_tpdm(struct >>>> coresight_device *csdev) >>>> CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM); >>>> } >>>> +static void tpdm_clear_element_size(struct coresight_device *csdev) >>>> +{ >>>> + struct tpda_drvdata *drvdata = >>>> dev_get_drvdata(csdev->dev.parent); >>>> + >>>> + if (drvdata->dsb_esize) >>>> + drvdata->dsb_esize = 0; >>>> + if (drvdata->cmb_esize) >>>> + drvdata->cmb_esize = 0; > > The ifs don't do anything here, it's just the same as always setting > to 0. I will update in the next patch series. > >>>> +} >>>> + >>>> +static void tpda_set_element_size(struct tpda_drvdata *drvdata, u32 >>>> *val) >>>> +{ >>>> + >>>> + if (drvdata->dsb_esize == 64) >>>> + *val |= TPDA_Pn_CR_DSBSIZE; >>>> + else if (drvdata->dsb_esize == 32) >>>> + *val &= ~TPDA_Pn_CR_DSBSIZE; >>>> + >>>> + if (drvdata->cmb_esize == 64) >>>> + *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x2); >>>> + else if (drvdata->cmb_esize == 32) >>>> + *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x1); >>>> + else if (drvdata->cmb_esize == 8) >>>> + *val &= ~TPDA_Pn_CR_CMBSIZE; >>>> +} >>>> + >>>> /* >>>> * Read the DSB element size from the TPDM device >>>> * Returns >>>> * The dsb element size read from the devicetree if available. >>> Hi Tao, >>> >>> I think the function description and the return value description above >>> need updating now. >> I will update this in the next patch series. >>> >>>> * 0 - Otherwise, with a warning once. >>>> */ >>>> -static int tpdm_read_dsb_element_size(struct coresight_device *csdev) >>>> +static int tpdm_read_element_size(struct tpda_drvdata *drvdata, >>>> + struct coresight_device *csdev) >>>> { >>>> - int rc = 0; >>>> - u8 size = 0; >>>> - >>>> - rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent), >>>> - "qcom,dsb-element-size", &size); >>>> + int rc = -EEXIST; >>>> + >>>> + if (!fwnode_property_read_u8(dev_fwnode(csdev->dev.parent), >>>> + "qcom,dsb-element-size", &drvdata->dsb_esize)) >>>> + rc &= 0; >>> Is &= 0 significant? Why not = 0? >> I will update this in the next patch series. >>> >>>> + if (!fwnode_property_read_u8(dev_fwnode(csdev->dev.parent), >>>> + "qcom,cmb-element-size", &drvdata->cmb_esize)) >>>> + rc &= 0; >>>> if (rc) >>>> dev_warn_once(&csdev->dev, >>>> - "Failed to read TPDM DSB Element size: %d\n", rc); >>>> + "Failed to read TPDM Element size: %d\n", rc); >>>> - return size; >>>> + return rc; >>>> } >>>> /* >>>> @@ -56,13 +86,17 @@ static int tpdm_read_dsb_element_size(struct >>>> coresight_device *csdev) >>>> * Parameter "inport" is used to pass in the input port number >>>> * of TPDA, and it is set to -1 in the recursize call. >>>> */ >>>> -static int tpda_get_element_size(struct coresight_device *csdev, >>>> +static int tpda_get_element_size(struct tpda_drvdata *drvdata, >>>> + struct coresight_device *csdev, >>>> int inport) >>>> { >>>> - int dsb_size = -ENOENT; >>>> - int i, size; >>>> + int rc = -ENOENT; >>>> + int i; >>>> struct coresight_device *in; >>>> + if (inport > 0) >>>> + tpdm_clear_element_size(csdev); >>>> + >>>> for (i = 0; i < csdev->pdata->nr_inconns; i++) { >>>> in = csdev->pdata->in_conns[i]->src_dev; >>>> if (!in) >>>> @@ -74,25 +108,20 @@ static int tpda_get_element_size(struct >>>> coresight_device *csdev, >>>> continue; >>>> if (coresight_device_is_tpdm(in)) { >>>> - size = tpdm_read_dsb_element_size(in); >>>> + if (rc) >>>> + rc = tpdm_read_element_size(drvdata, in); >>>> + else >>>> + return -EINVAL; >>> This is quite hard to follow, is checking rc here before calling >>> tpdm_read_element_size() some kind of way of only calling it once? >> >> Yes, there can only be one TPDM on one input port of TPDA. If >> "tpdm_read_element_size" is called >> >> twice, it means that two TPDMs are found on one input port of TPDA. >> >>> rc isn't actually a return value at this point, it's just default >>> initialised to -ENOENT. >> >> In this loop, "tpdm_read_element_size" will be called for the first time >> TPDM found. If rc equals to >> >> 0, it means that at lease one TPDM has been found on the input port. >> Does it make sense? >> >>> Then it's not clear why the else condition returns an error? >> The same as the above. >>> >>>> } else { >>>> /* Recurse down the path */ >>>> - size = tpda_get_element_size(in, -1); >>>> - } >>>> - >>>> - if (size < 0) >>>> - return size; >>>> - >>>> - if (dsb_size < 0) { >>>> - /* Found a size, save it. */ >>>> - dsb_size = size; >>>> - } else { >>>> - /* Found duplicate TPDMs */ >>>> - return -EEXIST; >>>> + rc = tpda_get_element_size(drvdata, in, -1); >>> And then why it's assigned here but not checked for an error in this >>> case? >> >> |Remote ETM| |TPDM| >> >> | branch0 | branch1 >> >> -------------------------- >> >> funnel1 >> >> --------------------------- >> >> | input port 1 >> >> ----------------------------- >> >> TPDA1 >> >> ----------------------------- >> >> The branches on some TPDA's input ports may not have TPDM. For example, >> branch 0 doesn't has a >> >> TPDM connected, tpda_get_element_size will not return 0 here. This is a >> normal situation. We need to >> >> continue to find TPDM on branch1 through recursion. >> >>> >>> Maybe some comments explaining the flow would help. Or to me it seems >>> like a second variable to track the thing that's actually intended >>> could >>> be used as well. Like "bool found_element" or something, rather than >>> re-using rc to also track another thing. >> >> Do you prefer to use "static bool found_element" to mark if we already >> have read an element size in >> >> the recursion function? >> > > You could add a static, or you could use whether a set dsb or cmb size > exists to mark that one was found, which I think is already partially > done. > > My confusion comes from the fact that instead of just a recursive > search, the function doesn't stop at the first found one, it continues > to sanity check that there is only one connected across all ports. > > And instead of just checking the error condition at the very end, it > does it mid recursion, relying on the rc value from a previous > iteration. IMO the following is a simplification because it always > returns at the first error found, and checks the final condition outside > of the recursive function. But you could probably leave it as you have > but with some comments explaining why: > > > diff --git a/drivers/hwtracing/coresight/coresight-tpda.c > b/drivers/hwtracing/coresight/coresight-tpda.c > index 3101d2a0671d..00b7607d36be 100644 > --- a/drivers/hwtracing/coresight/coresight-tpda.c > +++ b/drivers/hwtracing/coresight/coresight-tpda.c > @@ -90,13 +90,10 @@ static int tpda_get_element_size(struct > tpda_drvdata *drvdata, > struct coresight_device *csdev, > int inport) > { > - int rc = -ENOENT; > + int rc = 0; > int i; > struct coresight_device *in; > > - if (inport > 0) > - tpdm_clear_element_size(csdev); > - > for (i = 0; i < csdev->pdata->nr_inconns; i++) { > in = csdev->pdata->in_conns[i]->src_dev; > if (!in) > @@ -108,19 +105,23 @@ static int tpda_get_element_size(struct > tpda_drvdata *drvdata, > continue; > > if (coresight_device_is_tpdm(in)) { > - if (rc) > - rc = tpdm_read_element_size(drvdata, in); > - else > + if ((drvdata->dsb_esize) || > (drvdata->cmb_esize)) { > + /* Error if already previously found > and initialised one */ > + dev_warn_once(&drvdata->csdev->dev, > + "Detected multiple TPDMs on > port %d", -EEXIST); > return -EINVAL; > + } > + rc = tpdm_read_element_size(drvdata, in); > + if (rc) > + return rc; > } else { > /* Recurse down the path */ > rc = tpda_get_element_size(drvdata, in, -1); > + if (rc) > + return rc; > } > } > > - if ((drvdata->dsb_esize) || (drvdata->cmb_esize)) > - rc = 0; > - > return rc; > } > > @@ -146,15 +147,17 @@ static int tpda_enable_port(struct tpda_drvdata > *drvdata, int port) > * Set the bit to 0 if the size is 32 > * Set the bit to 1 if the size is 64 > */ > + tpdm_clear_element_size(drvdata->csdev); > rc = tpda_get_element_size(drvdata, drvdata->csdev, port); > - if (!rc) { > + if (!rc && ((drvdata->dsb_esize) || (drvdata->cmb_esize))) > + { > tpda_set_element_size(drvdata, &val); > /* Enable the port */ > val |= TPDA_Pn_CR_ENA; > writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port)); > - } else if (rc == -EINVAL) { > - dev_warn_once(&drvdata->csdev->dev, > - "Detected multiple TPDMs on port %d", -EEXIST); > + } else { > + dev_warn_once(&drvdata->csdev->dev, "Didn't find TPDM > elem size"); > + rc = -EINVAL; > } > > return rc; Make sense. I will refine and update the code in the next patch series. Best, Tao > >
diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c index 5f82737..3101d2a 100644 --- a/drivers/hwtracing/coresight/coresight-tpda.c +++ b/drivers/hwtracing/coresight/coresight-tpda.c @@ -28,24 +28,54 @@ static bool coresight_device_is_tpdm(struct coresight_device *csdev) CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM); } +static void tpdm_clear_element_size(struct coresight_device *csdev) +{ + struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + + if (drvdata->dsb_esize) + drvdata->dsb_esize = 0; + if (drvdata->cmb_esize) + drvdata->cmb_esize = 0; +} + +static void tpda_set_element_size(struct tpda_drvdata *drvdata, u32 *val) +{ + + if (drvdata->dsb_esize == 64) + *val |= TPDA_Pn_CR_DSBSIZE; + else if (drvdata->dsb_esize == 32) + *val &= ~TPDA_Pn_CR_DSBSIZE; + + if (drvdata->cmb_esize == 64) + *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x2); + else if (drvdata->cmb_esize == 32) + *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x1); + else if (drvdata->cmb_esize == 8) + *val &= ~TPDA_Pn_CR_CMBSIZE; +} + /* * Read the DSB element size from the TPDM device * Returns * The dsb element size read from the devicetree if available. * 0 - Otherwise, with a warning once. */ -static int tpdm_read_dsb_element_size(struct coresight_device *csdev) +static int tpdm_read_element_size(struct tpda_drvdata *drvdata, + struct coresight_device *csdev) { - int rc = 0; - u8 size = 0; - - rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent), - "qcom,dsb-element-size", &size); + int rc = -EEXIST; + + if (!fwnode_property_read_u8(dev_fwnode(csdev->dev.parent), + "qcom,dsb-element-size", &drvdata->dsb_esize)) + rc &= 0; + if (!fwnode_property_read_u8(dev_fwnode(csdev->dev.parent), + "qcom,cmb-element-size", &drvdata->cmb_esize)) + rc &= 0; if (rc) dev_warn_once(&csdev->dev, - "Failed to read TPDM DSB Element size: %d\n", rc); + "Failed to read TPDM Element size: %d\n", rc); - return size; + return rc; } /* @@ -56,13 +86,17 @@ static int tpdm_read_dsb_element_size(struct coresight_device *csdev) * Parameter "inport" is used to pass in the input port number * of TPDA, and it is set to -1 in the recursize call. */ -static int tpda_get_element_size(struct coresight_device *csdev, +static int tpda_get_element_size(struct tpda_drvdata *drvdata, + struct coresight_device *csdev, int inport) { - int dsb_size = -ENOENT; - int i, size; + int rc = -ENOENT; + int i; struct coresight_device *in; + if (inport > 0) + tpdm_clear_element_size(csdev); + for (i = 0; i < csdev->pdata->nr_inconns; i++) { in = csdev->pdata->in_conns[i]->src_dev; if (!in) @@ -74,25 +108,20 @@ static int tpda_get_element_size(struct coresight_device *csdev, continue; if (coresight_device_is_tpdm(in)) { - size = tpdm_read_dsb_element_size(in); + if (rc) + rc = tpdm_read_element_size(drvdata, in); + else + return -EINVAL; } else { /* Recurse down the path */ - size = tpda_get_element_size(in, -1); - } - - if (size < 0) - return size; - - if (dsb_size < 0) { - /* Found a size, save it. */ - dsb_size = size; - } else { - /* Found duplicate TPDMs */ - return -EEXIST; + rc = tpda_get_element_size(drvdata, in, -1); } } - return dsb_size; + if ((drvdata->dsb_esize) || (drvdata->cmb_esize)) + rc = 0; + + return rc; } /* Settings pre enabling port control register */ @@ -109,7 +138,7 @@ static void tpda_enable_pre_port(struct tpda_drvdata *drvdata) static int tpda_enable_port(struct tpda_drvdata *drvdata, int port) { u32 val; - int size; + int rc; val = readl_relaxed(drvdata->base + TPDA_Pn_CR(port)); /* @@ -117,29 +146,18 @@ static int tpda_enable_port(struct tpda_drvdata *drvdata, int port) * Set the bit to 0 if the size is 32 * Set the bit to 1 if the size is 64 */ - size = tpda_get_element_size(drvdata->csdev, port); - switch (size) { - case 32: - val &= ~TPDA_Pn_CR_DSBSIZE; - break; - case 64: - val |= TPDA_Pn_CR_DSBSIZE; - break; - case 0: - return -EEXIST; - case -EEXIST: + rc = tpda_get_element_size(drvdata, drvdata->csdev, port); + if (!rc) { + tpda_set_element_size(drvdata, &val); + /* Enable the port */ + val |= TPDA_Pn_CR_ENA; + writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port)); + } else if (rc == -EINVAL) { dev_warn_once(&drvdata->csdev->dev, "Detected multiple TPDMs on port %d", -EEXIST); - return -EEXIST; - default: - return -EINVAL; } - /* Enable the port */ - val |= TPDA_Pn_CR_ENA; - writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port)); - - return 0; + return rc; } static int __tpda_enable(struct tpda_drvdata *drvdata, int port) diff --git a/drivers/hwtracing/coresight/coresight-tpda.h b/drivers/hwtracing/coresight/coresight-tpda.h index b3b38fd..29164fd 100644 --- a/drivers/hwtracing/coresight/coresight-tpda.h +++ b/drivers/hwtracing/coresight/coresight-tpda.h @@ -10,6 +10,8 @@ #define TPDA_Pn_CR(n) (0x004 + (n * 4)) /* Aggregator port enable bit */ #define TPDA_Pn_CR_ENA BIT(0) +/* Aggregator port CMB data set element size bit */ +#define TPDA_Pn_CR_CMBSIZE GENMASK(7, 6) /* Aggregator port DSB data set element size bit */ #define TPDA_Pn_CR_DSBSIZE BIT(8) @@ -25,6 +27,8 @@ * @csdev: component vitals needed by the framework. * @spinlock: lock for the drvdata value. * @enable: enable status of the component. + * @dsb_esize Record the DSB element size. + * @cmb_esize Record the CMB element size. */ struct tpda_drvdata { void __iomem *base; @@ -32,6 +36,8 @@ struct tpda_drvdata { struct coresight_device *csdev; spinlock_t spinlock; u8 atid; + u8 dsb_esize; + u8 cmb_esize; }; #endif /* _CORESIGHT_CORESIGHT_TPDA_H */