From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D53D53D8132 for ; Thu, 2 Jul 2026 08:54:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782982497; cv=none; b=WbC6FPEVzdx59Xez/YsPLxgRV3YDfgth3XyzHwqjlJfbw4uc+UYCOYu8LwC/lNlsRDJHiyQhj9a4u/rWuOCaqTFZJVSyu/euGVWr7PNRRqYcKTqzm5RuPoxhL82etlzj5GirX1ySunlcdQoLv7Yx+ywvoJ1vQXS/zmx+o5/lgCU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782982497; c=relaxed/simple; bh=Q6tE3QCsZcbp/Lxk9tJoa+uyS/qXdWg0T3PWWYstidk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZNQX3HgSO4ebLTvPMg65uPEGLWIOsIop20WfLiexOt9Iz6DO9TnijjxDwYUpcrHTSYewyYe9G9TT4vNT5rikT/3h82VqJ6fI3h1UeuisPJuoi9xhPVvoTw1l9EGs6CSKGr/dPHJ2rmq0VuR1tNsutOop8Pik9OgGhQWvM4Jmggg= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=MqR/XBsZ; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=jbhT94/j; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="MqR/XBsZ"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="jbhT94/j" Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 6624iPQQ3592225 for ; Thu, 2 Jul 2026 08:54:51 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= 9b/W7QGSCQ7+siyAOGDr0r/H8HglDIhkhzvNu/L2LPw=; b=MqR/XBsZP67EIomQ V5Ln9ipKy8ZfVDbnX6Ohxmk6GMvxeUdy6zqDg1YoBgeFX5JmV67bb0tnulHerPDM fjc77GP1cdm2rX8iqfYoT02/LHrQj5GbeUe7i2GxTOMLsMAubekVzRGARG9OrkMX s7H/AuKDgf6BV8Hi0NrjgaLyBryZrA2X73xc4lJEqZFC5SAU+tvGRWYfzdAuiof4 rUX1rXsnD1kgKyd/dNFNp6QxkhHohV3PlwkJbVr17tw+ohydz3uR0uk2CsBkn7JV X9deovm4Sw0Jd11xk2/YwyQZc5gAco4rWvaWnwFl8WdAXASgRWf5uSgxGuv/rK7o EGs+Tw== Received: from mail-pf1-f200.google.com (mail-pf1-f200.google.com [209.85.210.200]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4f5h7n8w8v-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 02 Jul 2026 08:54:51 +0000 (GMT) Received: by mail-pf1-f200.google.com with SMTP id d2e1a72fcca58-8479586724eso1792701b3a.2 for ; Thu, 02 Jul 2026 01:54:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1782982491; x=1783587291; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=9b/W7QGSCQ7+siyAOGDr0r/H8HglDIhkhzvNu/L2LPw=; b=jbhT94/jsO1z5N10gdl/mjjvI7yj/7V85FFZoWJ4e5wu5HP7ZafBF8+NfJ1MmiDaqT w1qy0I0ECAg4CTMczkHOJSMoya8GaDuXRo8VVcDLNkoBIxJhz9xTdYh/mpPL11ZQiszn LiZ6Ybqsje3WJ3H/VKeCPdUZNjKIxouAS3/4ysGPSXecnG7Z9R4nc04NHoml4jP3qaOi 3WEu7VjNlvas/nJEja6nAjx+HizA3w9J0TQGyCbXUAY6J/M6mxp8Ox7V/1ydJVBkOWoH QqaztDY44TjW2+QdoF/HR4p9r4tGOC6snGD+i0RldrRhcDPiF/8wd4lYzhdFYp1GlYP2 uJ7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782982491; x=1783587291; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=9b/W7QGSCQ7+siyAOGDr0r/H8HglDIhkhzvNu/L2LPw=; b=eHv3OiO1X4LQb6yiQcKaBDl4sAMX3e+AF0ZOZLboHvlxrOVWh3Uyzcqa/0mK62nGTV Dp2YdqXLfouOTlhvXMA7acxZvk7RgnfBO8HtM8lYN0dXpLo/EC1foBbSnJoLqWzDSwsr FFaW4XrFkSFJ0s7o+KqB285Q0o3IZaxuyS11vyf0V5m75npmY6iFhi0mgpS5VQmHcxLX DCldNC4kJaZtossScTAyrk+yCxsA6tB4qu05SvynaiptTlE5YGkDTkEKhBkgz5KfjMUU 5Wb3NRuW4VRSZzWMUQ7hmE+uBGHPv1+AmJbzQ0pvxoaDfBhoQwXGcvJu4I5gWGn4Ie5O Jb5w== X-Forwarded-Encrypted: i=1; AFNElJ8e2lEuPKYlzhUX8oaULCOtzmBlNZXsZkEXJJ68zTdAlMTkRvtVfG55+WcpjKgUARDEXPIAPJenu18YRCM=@vger.kernel.org X-Gm-Message-State: AOJu0YwDLb62E1+jef5IsxYG/8FLtvrAkvvarygU4jdrhHHd4RcTITYW ZVu29HbvcK1lAhWh0MMaLC6wXlssfA1DkZpnfm1nPXJz1qZ2xHXO7Mo+1hgHChEr2jzqJHMeNeH slzbS4mKC5o16SeDYpiRlaf6odadeYrWe3AZl202izSuSuiHerx503Jz/rmW93UXEAQs= X-Gm-Gg: AfdE7ckyCBOdZyZPujBAESWUhS16YD+YHzLaYChXdsOFJN3u/owcgsDIFklUi4L8/fh 4BymhxDp2PQulnrLJx1EI8Zhx+OvjZayN+nAdd8DpqF6+PTWTKzVr5UQ0TwzI8hhgczqw7FkJny MgEMj9/ECMOTLvFIuM63fafln4kiTIOMpkHIiBA5Em4IQ8KzTPFGekNXAbfgwwQk59VSP0kankq T8GZOxBblSIuB0SHNqPe2Zw9BX40ibLVc4GhKuMQL5uTbKwezZfoK5OQTvoP/Phkw/dbXNJFYul KPJinPhx0fj/hmj2XnoRQ7aZ0H5J+sMas9iilo0/pv1fnLrzzFeDL/tayhbDb6m+eanArXOvl77 Ct+HNC6qxqyfKzsbm0jS68QV0M0yZKR6VYyrNbTeXNm74Vm/auSlAua9Tvh6b+zq8AoUrlJ6wOg == X-Received: by 2002:a05:6a00:1392:b0:847:8d2d:713c with SMTP id d2e1a72fcca58-847c5193970mr3962649b3a.50.1782982490343; Thu, 02 Jul 2026 01:54:50 -0700 (PDT) X-Received: by 2002:a05:6a00:1392:b0:847:8d2d:713c with SMTP id d2e1a72fcca58-847c5193970mr3962604b3a.50.1782982489602; Thu, 02 Jul 2026 01:54:49 -0700 (PDT) Received: from jiegan-gv.ap.qualcomm.com (tpe-colo-wan-fw-bordernet.qualcomm.com. [103.229.16.4]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-847cb7933e1sm1003514b3a.26.2026.07.02.01.54.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Jul 2026 01:54:49 -0700 (PDT) From: Jie Gan Date: Thu, 02 Jul 2026 16:54:19 +0800 Subject: [PATCH v2 1/2] coresight: Fix clock refcount imbalance on platform remove Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260702-fix-clock-refcount-unbalance-v2-1-2383fbb9952e@oss.qualcomm.com> References: <20260702-fix-clock-refcount-unbalance-v2-0-2383fbb9952e@oss.qualcomm.com> In-Reply-To: <20260702-fix-clock-refcount-unbalance-v2-0-2383fbb9952e@oss.qualcomm.com> To: Suzuki K Poulose , Mike Leach , James Clark , Leo Yan , Alexander Shishkin , Anshuman Khandual , Yeoreum Yun , Yuanfang Zhang , Maxime Coquelin , Alexandre Torgue , Tingwei Zhang Cc: coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com, Jie Gan X-Mailer: b4 0.14.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1782982477; l=17419; i=jie.gan@oss.qualcomm.com; s=20250909; h=from:subject:message-id; bh=Q6tE3QCsZcbp/Lxk9tJoa+uyS/qXdWg0T3PWWYstidk=; b=9nc6eQUyghpOxTnqUETz42quTo3iHXWtnFsF0615lhSNzxWwcuW83gmHcJulqE0oie83nBI9a HAIu6TYgclfDVsX/veCSfGmEXd0rr/OGb7szoGuWXcQzF2UCi4CHZkM X-Developer-Key: i=jie.gan@oss.qualcomm.com; a=ed25519; pk=3LxxUZRPCNkvPDlWOvXfJNqNO4SfGdy3eghMb8puHuk= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzAyMDA5MSBTYWx0ZWRfX/JRo+kCbL+J/ 1FuvxPnJ5iIao0RGLnBEYiQ3GSOgeWJQZ0wCabLmeew7SaGVcnMBKtr9u8TSLfWJ5HjcsNd3ckB JZM1h9Az0fh6KNExLOSQRJaK95verELVV94gMfo+sANxYoUw01Nh+xCw+kkshS1jtxwBwEJ84yN PgwbOZXxpvU1xa7V5Iiv9TeQFXJIFcMoZME5lbEQVBm6HI5D/RgTVjfUTxH4yLu6LNPZrtGeFNx OfF7CGs89MQ3ABq2MdJqJfoM7EOYjFNakpGMWuW5Eji6oW2Gw3RlSHD1fc6NQItTr7xJ0NpF8sF Sgy6oq+hIZVzXqWe/ZN0KmA03NaRktvakicRUG1CAFV02bC81Ft/qbQCyvk2r2+JEvwn6UwXAxt UPY236QCHEgzGStK9k9Ta/2N1ED8b9L6piIpKjrlEyv05t39Mz6OlQNGFfUUT59rHjIZ0v/KifV 6Tp/Ozir8ro2ZQE0J6w== X-Proofpoint-ORIG-GUID: nJM8T6uYiGAeb6EvmEHl8E9UoeXffRDJ X-Proofpoint-Spam-Info: AW1haW4tMjYwNzAyMDA5MSBTYWx0ZWRfXx2zLWV6rr9Fp W+cZaHAXiglhvqyi9iuQTI8Ep0CSzPeTC8YPPm1yrugiHnMWdVEsHWby8IfnJ4EA+dL5Mhv+YiA N3s/btYiar+o8chQMtWj2T0CTZQe4DU= X-Proofpoint-GUID: nJM8T6uYiGAeb6EvmEHl8E9UoeXffRDJ X-Authority-Analysis: v=2.4 cv=WMBPmHsR c=1 sm=1 tr=0 ts=6a46275b cx=c_pps a=mDZGXZTwRPZaeRUbqKGCBw==:117 a=nuhDOHQX5FNHPW3J6Bj6AA==:17 a=IkcTkHD0fZMA:10 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yOCtJkima9RkubShWh1s:22 a=7CQSdrXTAAAA:8 a=EUspDBNiAAAA:8 a=hqFQHrWFFG5QrmS-gPsA:9 a=QEXdDO2ut3YA:10 a=zc0IvFSfCIW2DFIPzwfm:22 a=a-qgeE7W1pNrGK8U0ZQC:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-07-02_01,2026-06-26_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 phishscore=0 suspectscore=0 lowpriorityscore=0 bulkscore=0 spamscore=0 priorityscore=1501 adultscore=0 impostorscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607020091 coresight_get_enable_clocks() enables the programming clock and the optional AT clock through devm_clk_get_optional_enabled(), which also registers a devm action to call clk_disable_unprepare() when the driver detaches. After probe, pm_runtime_put() allows the device to suspend and the runtime suspend callback disables the same clocks. During remove the device is left runtime suspended, so pm_runtime_disable() freezes it with the clocks already disabled. The devm cleanup that runs afterwards calls clk_disable_unprepare() a second time, underflowing the clock enable refcount. Resume the device with pm_runtime_get_sync() before tearing it down so the clocks are enabled again and balance the devm-managed disable. Then pm_runtime_set_suspended() and pm_runtime_put_noidle() leave the device in a coherent runtime PM state (suspended, usage count balanced) once the devm action has disabled the clocks. This affects all CoreSight platform drivers that obtain their clocks through coresight_get_enable_clocks(): catu, cpu-debug, ctcu, etm4x, funnel, replicator, stm, tmc and tpiu. Fixes: 1abc1b212eff ("coresight: Appropriately disable programming clocks") Reviewed-by: Yeoreum Yun Signed-off-by: Jie Gan --- drivers/hwtracing/coresight/coresight-catu.c | 8 ++++++++ drivers/hwtracing/coresight/coresight-cpu-debug.c | 8 ++++++++ drivers/hwtracing/coresight/coresight-ctcu-core.c | 8 ++++++++ drivers/hwtracing/coresight/coresight-etm4x-core.c | 8 ++++++++ drivers/hwtracing/coresight/coresight-funnel.c | 8 ++++++++ drivers/hwtracing/coresight/coresight-replicator.c | 8 ++++++++ drivers/hwtracing/coresight/coresight-stm.c | 8 ++++++++ drivers/hwtracing/coresight/coresight-tmc-core.c | 8 ++++++++ drivers/hwtracing/coresight/coresight-tpiu.c | 8 ++++++++ 9 files changed, 72 insertions(+) diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c index ad8dafea7d2f..b72fa7f4bdeb 100644 --- a/drivers/hwtracing/coresight/coresight-catu.c +++ b/drivers/hwtracing/coresight/coresight-catu.c @@ -629,42 +629,50 @@ static int catu_platform_probe(struct platform_device *pdev) pm_runtime_get_noresume(&pdev->dev); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); ret = __catu_probe(&pdev->dev, res); pm_runtime_put(&pdev->dev); if (ret) pm_runtime_disable(&pdev->dev); return ret; } static void catu_platform_remove(struct platform_device *pdev) { struct catu_drvdata *drvdata = dev_get_drvdata(&pdev->dev); if (WARN_ON(!drvdata)) return; + /* + * Resume the device so its clocks are enabled again, balancing the + * clk_disable_unprepare() that devm runs when the driver detaches. + * Then mark it suspended and drop the usage count taken here. + */ + pm_runtime_get_sync(&pdev->dev); __catu_remove(&pdev->dev); pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); } #ifdef CONFIG_PM static int catu_runtime_suspend(struct device *dev) { struct catu_drvdata *drvdata = dev_get_drvdata(dev); clk_disable_unprepare(drvdata->atclk); clk_disable_unprepare(drvdata->pclk); return 0; } static int catu_runtime_resume(struct device *dev) { struct catu_drvdata *drvdata = dev_get_drvdata(dev); int ret; ret = clk_prepare_enable(drvdata->pclk); if (ret) diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c index 3a806c1d50ea..87b39874461e 100644 --- a/drivers/hwtracing/coresight/coresight-cpu-debug.c +++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c @@ -693,42 +693,50 @@ static int debug_platform_probe(struct platform_device *pdev) pm_runtime_get_noresume(&pdev->dev); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); ret = __debug_probe(&pdev->dev, res); if (ret) { pm_runtime_put_noidle(&pdev->dev); pm_runtime_disable(&pdev->dev); } return ret; } static void debug_platform_remove(struct platform_device *pdev) { struct debug_drvdata *drvdata = dev_get_drvdata(&pdev->dev); if (WARN_ON(!drvdata)) return; + /* + * Resume the device so its clocks are enabled again, balancing the + * clk_disable_unprepare() that devm runs when the driver detaches. + * Then mark it suspended and drop the usage count taken here. + */ + pm_runtime_get_sync(&pdev->dev); __debug_remove(&pdev->dev); pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); } #ifdef CONFIG_ACPI static const struct acpi_device_id debug_platform_ids[] = { {"ARMHC503", 0, 0, 0}, /* ARM CoreSight Debug */ {}, }; MODULE_DEVICE_TABLE(acpi, debug_platform_ids); #endif #ifdef CONFIG_PM static int debug_runtime_suspend(struct device *dev) { struct debug_drvdata *drvdata = dev_get_drvdata(dev); clk_disable_unprepare(drvdata->pclk); return 0; } diff --git a/drivers/hwtracing/coresight/coresight-ctcu-core.c b/drivers/hwtracing/coresight/coresight-ctcu-core.c index 9043cad42f01..e0e33e3ca5bf 100644 --- a/drivers/hwtracing/coresight/coresight-ctcu-core.c +++ b/drivers/hwtracing/coresight/coresight-ctcu-core.c @@ -248,42 +248,50 @@ static int ctcu_platform_probe(struct platform_device *pdev) pm_runtime_get_noresume(&pdev->dev); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); ret = ctcu_probe(pdev); pm_runtime_put(&pdev->dev); if (ret) pm_runtime_disable(&pdev->dev); return ret; } static void ctcu_platform_remove(struct platform_device *pdev) { struct ctcu_drvdata *drvdata = platform_get_drvdata(pdev); if (WARN_ON(!drvdata)) return; + /* + * Resume the device so its clocks are enabled again, balancing the + * clk_disable_unprepare() that devm runs when the driver detaches. + * Then mark it suspended and drop the usage count taken here. + */ + pm_runtime_get_sync(&pdev->dev); ctcu_remove(pdev); pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); } #ifdef CONFIG_PM static int ctcu_runtime_suspend(struct device *dev) { struct ctcu_drvdata *drvdata = dev_get_drvdata(dev); clk_disable_unprepare(drvdata->apb_clk); return 0; } static int ctcu_runtime_resume(struct device *dev) { struct ctcu_drvdata *drvdata = dev_get_drvdata(dev); return clk_prepare_enable(drvdata->apb_clk); } #endif diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index 14bb31bd6a0b..a3ae8e1e3a1b 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -2399,41 +2399,49 @@ static void etm4_remove_dev(struct etmv4_drvdata *drvdata) etm_perf_symlink(drvdata->csdev, false); cscfg_unregister_csdev(drvdata->csdev); coresight_unregister(drvdata->csdev); } } static void etm4_remove_amba(struct amba_device *adev) { struct etmv4_drvdata *drvdata = dev_get_drvdata(&adev->dev); if (drvdata) etm4_remove_dev(drvdata); } static void etm4_remove_platform_dev(struct platform_device *pdev) { struct etmv4_drvdata *drvdata = dev_get_drvdata(&pdev->dev); if (drvdata) etm4_remove_dev(drvdata); + /* + * Resume the device so its clocks are enabled again, balancing the + * clk_disable_unprepare() that devm runs when the driver detaches. + * Then mark it suspended and drop the usage count taken here. + */ + pm_runtime_get_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); } static const struct amba_id etm4_ids[] = { CS_AMBA_ID(0x000bb95d), /* Cortex-A53 */ CS_AMBA_ID(0x000bb95e), /* Cortex-A57 */ CS_AMBA_ID(0x000bb95a), /* Cortex-A72 */ CS_AMBA_ID(0x000bb959), /* Cortex-A73 */ CS_AMBA_UCI_ID(0x000bb9da, uci_id_etm4),/* Cortex-A35 */ CS_AMBA_UCI_ID(0x000bbd05, uci_id_etm4),/* Cortex-A55 */ CS_AMBA_UCI_ID(0x000bbd0a, uci_id_etm4),/* Cortex-A75 */ CS_AMBA_UCI_ID(0x000bbd0c, uci_id_etm4),/* Neoverse N1 */ CS_AMBA_UCI_ID(0x000bbd41, uci_id_etm4),/* Cortex-A78 */ CS_AMBA_UCI_ID(0x000f0205, uci_id_etm4),/* Qualcomm Kryo */ CS_AMBA_UCI_ID(0x000f0211, uci_id_etm4),/* Qualcomm Kryo */ CS_AMBA_UCI_ID(0x000bb802, uci_id_etm4),/* Qualcomm Kryo 385 Cortex-A55 */ CS_AMBA_UCI_ID(0x000bb803, uci_id_etm4),/* Qualcomm Kryo 385 Cortex-A75 */ CS_AMBA_UCI_ID(0x000bb805, uci_id_etm4),/* Qualcomm Kryo 4XX Cortex-A55 */ CS_AMBA_UCI_ID(0x000bb804, uci_id_etm4),/* Qualcomm Kryo 4XX Cortex-A76 */ CS_AMBA_UCI_ID(0x000bbd0d, uci_id_etm4),/* Qualcomm Kryo 5XX Cortex-A77 */ CS_AMBA_UCI_ID(0x000cc0af, uci_id_etm4),/* Marvell ThunderX2 */ diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c index 0abc11f0690c..d69cd66e8394 100644 --- a/drivers/hwtracing/coresight/coresight-funnel.c +++ b/drivers/hwtracing/coresight/coresight-funnel.c @@ -316,42 +316,50 @@ static int funnel_platform_probe(struct platform_device *pdev) pm_runtime_get_noresume(&pdev->dev); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); ret = funnel_probe(&pdev->dev, res); pm_runtime_put(&pdev->dev); if (ret) pm_runtime_disable(&pdev->dev); return ret; } static void funnel_platform_remove(struct platform_device *pdev) { struct funnel_drvdata *drvdata = dev_get_drvdata(&pdev->dev); if (WARN_ON(!drvdata)) return; + /* + * Resume the device so its clocks are enabled again, balancing the + * clk_disable_unprepare() that devm runs when the driver detaches. + * Then mark it suspended and drop the usage count taken here. + */ + pm_runtime_get_sync(&pdev->dev); funnel_remove(&pdev->dev); pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); } static const struct of_device_id funnel_match[] = { {.compatible = "arm,coresight-static-funnel"}, {} }; MODULE_DEVICE_TABLE(of, funnel_match); #ifdef CONFIG_ACPI static const struct acpi_device_id funnel_acpi_ids[] = { {"ARMHC9FE", 0, 0, 0}, /* ARM Coresight Static Funnel */ {"ARMHC9FF", 0, 0, 0}, /* ARM CoreSight Dynamic Funnel */ {}, }; MODULE_DEVICE_TABLE(acpi, funnel_acpi_ids); #endif static struct platform_driver funnel_driver = { diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c index 2f382de357ee..1df01deb2f69 100644 --- a/drivers/hwtracing/coresight/coresight-replicator.c +++ b/drivers/hwtracing/coresight/coresight-replicator.c @@ -295,42 +295,50 @@ static int replicator_platform_probe(struct platform_device *pdev) pm_runtime_get_noresume(&pdev->dev); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); ret = replicator_probe(&pdev->dev, res); pm_runtime_put(&pdev->dev); if (ret) pm_runtime_disable(&pdev->dev); return ret; } static void replicator_platform_remove(struct platform_device *pdev) { struct replicator_drvdata *drvdata = dev_get_drvdata(&pdev->dev); if (WARN_ON(!drvdata)) return; + /* + * Resume the device so its clocks are enabled again, balancing the + * clk_disable_unprepare() that devm runs when the driver detaches. + * Then mark it suspended and drop the usage count taken here. + */ + pm_runtime_get_sync(&pdev->dev); replicator_remove(&pdev->dev); pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); } #ifdef CONFIG_PM static int replicator_runtime_suspend(struct device *dev) { struct replicator_drvdata *drvdata = dev_get_drvdata(dev); clk_disable_unprepare(drvdata->atclk); clk_disable_unprepare(drvdata->pclk); return 0; } static int replicator_runtime_resume(struct device *dev) { struct replicator_drvdata *drvdata = dev_get_drvdata(dev); int ret; ret = clk_prepare_enable(drvdata->pclk); if (ret) diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c index 4e860519a73f..a75b1c56a867 100644 --- a/drivers/hwtracing/coresight/coresight-stm.c +++ b/drivers/hwtracing/coresight/coresight-stm.c @@ -1008,42 +1008,50 @@ static int stm_platform_probe(struct platform_device *pdev) pm_runtime_get_noresume(&pdev->dev); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); ret = __stm_probe(&pdev->dev, res); pm_runtime_put(&pdev->dev); if (ret) pm_runtime_disable(&pdev->dev); return ret; } static void stm_platform_remove(struct platform_device *pdev) { struct stm_drvdata *drvdata = dev_get_drvdata(&pdev->dev); if (WARN_ON(!drvdata)) return; + /* + * Resume the device so its clocks are enabled again, balancing the + * clk_disable_unprepare() that devm runs when the driver detaches. + * Then mark it suspended and drop the usage count taken here. + */ + pm_runtime_get_sync(&pdev->dev); __stm_remove(&pdev->dev); pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); } #ifdef CONFIG_ACPI static const struct acpi_device_id stm_acpi_ids[] = { {"ARMHC502", 0, 0, 0}, /* ARM CoreSight STM */ {}, }; MODULE_DEVICE_TABLE(acpi, stm_acpi_ids); #endif static struct platform_driver stm_platform_driver = { .probe = stm_platform_probe, .remove = stm_platform_remove, .driver = { .name = "coresight-stm-platform", .acpi_match_table = ACPI_PTR(stm_acpi_ids), .suppress_bind_attrs = true, .pm = &stm_dev_pm_ops, }, }; diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c index bc5a133ada3e..ed40bfea32f9 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-core.c +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c @@ -971,42 +971,50 @@ static int tmc_platform_probe(struct platform_device *pdev) pm_runtime_get_noresume(&pdev->dev); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); ret = __tmc_probe(&pdev->dev, res); pm_runtime_put(&pdev->dev); if (ret) pm_runtime_disable(&pdev->dev); return ret; } static void tmc_platform_remove(struct platform_device *pdev) { struct tmc_drvdata *drvdata = dev_get_drvdata(&pdev->dev); if (WARN_ON(!drvdata)) return; + /* + * Resume the device so its clocks are enabled again, balancing the + * clk_disable_unprepare() that devm runs when the driver detaches. + * Then mark it suspended and drop the usage count taken here. + */ + pm_runtime_get_sync(&pdev->dev); __tmc_remove(&pdev->dev); pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); } #ifdef CONFIG_PM static int tmc_runtime_suspend(struct device *dev) { struct tmc_drvdata *drvdata = dev_get_drvdata(dev); clk_disable_unprepare(drvdata->atclk); clk_disable_unprepare(drvdata->pclk); return 0; } static int tmc_runtime_resume(struct device *dev) { struct tmc_drvdata *drvdata = dev_get_drvdata(dev); int ret; ret = clk_prepare_enable(drvdata->pclk); if (ret) diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c index 7b029d2eb389..775507d0bb36 100644 --- a/drivers/hwtracing/coresight/coresight-tpiu.c +++ b/drivers/hwtracing/coresight/coresight-tpiu.c @@ -268,42 +268,50 @@ static int tpiu_platform_probe(struct platform_device *pdev) pm_runtime_get_noresume(&pdev->dev); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); ret = __tpiu_probe(&pdev->dev, res); pm_runtime_put(&pdev->dev); if (ret) pm_runtime_disable(&pdev->dev); return ret; } static void tpiu_platform_remove(struct platform_device *pdev) { struct tpiu_drvdata *drvdata = dev_get_drvdata(&pdev->dev); if (WARN_ON(!drvdata)) return; + /* + * Resume the device so its clocks are enabled again, balancing the + * clk_disable_unprepare() that devm runs when the driver detaches. + * Then mark it suspended and drop the usage count taken here. + */ + pm_runtime_get_sync(&pdev->dev); __tpiu_remove(&pdev->dev); pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); } #ifdef CONFIG_ACPI static const struct acpi_device_id tpiu_acpi_ids[] = { {"ARMHC979", 0, 0, 0}, /* ARM CoreSight TPIU */ {} }; MODULE_DEVICE_TABLE(acpi, tpiu_acpi_ids); #endif static struct platform_driver tpiu_platform_driver = { .probe = tpiu_platform_probe, .remove = tpiu_platform_remove, .driver = { .name = "coresight-tpiu-platform", .acpi_match_table = ACPI_PTR(tpiu_acpi_ids), .suppress_bind_attrs = true, .pm = &tpiu_dev_pm_ops, }, }; -- 2.34.1