* [PATCH v3 0/9] coresight: Fix and improve clock usage
@ 2025-06-09 16:00 Leo Yan
2025-06-09 16:00 ` [PATCH v3 1/9] coresight: tmc: Support atclk Leo Yan
` (8 more replies)
0 siblings, 9 replies; 24+ messages in thread
From: Leo Yan @ 2025-06-09 16:00 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Anshuman Khandual,
Alexander Shishkin, Greg Kroah-Hartman
Cc: coresight, linux-arm-kernel, linux-kernel, Leo Yan
This series fixes and improves clock usage in the Arm CoreSight drivers.
Based on the DT binding documents, the trace clock (atclk) is defined in
some CoreSight modules, but support is absent. In most cases, the issue
is hidden because the atclk clock is shared by multiple CoreSight
modules and the clock is enabled anyway by other drivers. The first
three patches address this issue.
The programming clock (pclk) management in CoreSight drivers does not
use the devm_XXX() variant APIs, the drivers needs to manually disable
and release clocks for errors and for normal module exit. However, the
drivers miss to disable clocks during module exit. The atclk may also
not be disabled in CoreSight drivers during module exit. By using devm
APIs, patches 04 and 05 fix clock disabling issues.
Another issue is pclk might be enabled twice in init phase - once by
AMBA bus driver, and again by CoreSight drivers. This is fixed in
patch 06.
Patches 07 to 09 refactor the clock related code. Patch 07 consolidats
the clock initialization into a central place. Patch 08 makes the
clock enabling sequence consistent. Patch 09 removes redundant
condition checks and adds error handling in runtime PM.
This series has been verified on Arm64 Hikey960 and Juno platforms.
Changes from v2:
- Updated subjects for patches 04 and 05 (Anshuman).
- Refined condition checking "if (dev_is_amba(dev))" in patch 07
(Anshuman).
Changes from v1:
- Moved the coresight_get_enable_clocks() function into CoreSight core
layer (James).
- Added comments for clock naming "apb_pclk" and "apb" (James).
- Re-ordered patches for easier understanding (Anshuman).
- Minor improvement for commit log in patch 01 (Anshuman).
Signed-off-by: Leo Yan <leo.yan@arm.com>
---
Leo Yan (9):
coresight: tmc: Support atclk
coresight: catu: Support atclk
coresight: etm4x: Support atclk
coresight: Appropriately disable programming clocks
coresight: Appropriately disable trace bus clocks
coresight: Avoid enable programming clock duplicately
coresight: Consolidate clock enabling
coresight: Make clock sequence consistent
coresight: Refactor runtime PM
drivers/hwtracing/coresight/coresight-catu.c | 53 ++++++++---------
drivers/hwtracing/coresight/coresight-catu.h | 1 +
drivers/hwtracing/coresight/coresight-core.c | 45 +++++++++++++++
drivers/hwtracing/coresight/coresight-cpu-debug.c | 41 +++++---------
drivers/hwtracing/coresight/coresight-ctcu-core.c | 24 +++-----
drivers/hwtracing/coresight/coresight-etb10.c | 18 ++----
drivers/hwtracing/coresight/coresight-etm3x-core.c | 17 ++----
drivers/hwtracing/coresight/coresight-etm4x-core.c | 32 ++++++-----
drivers/hwtracing/coresight/coresight-etm4x.h | 4 +-
drivers/hwtracing/coresight/coresight-funnel.c | 66 ++++++++--------------
drivers/hwtracing/coresight/coresight-replicator.c | 63 ++++++++-------------
drivers/hwtracing/coresight/coresight-stm.c | 34 +++++------
drivers/hwtracing/coresight/coresight-tmc-core.c | 48 ++++++++--------
drivers/hwtracing/coresight/coresight-tmc.h | 2 +
drivers/hwtracing/coresight/coresight-tpiu.c | 36 +++++-------
include/linux/coresight.h | 30 +---------
16 files changed, 225 insertions(+), 289 deletions(-)
---
base-commit: 408c97c4a5e0b634dcd15bf8b8808b382e888164
change-id: 20250609-arm_cs_fix_clock_v3_public-d546e8bfc852
Best regards,
--
Leo Yan <leo.yan@arm.com>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v3 1/9] coresight: tmc: Support atclk
2025-06-09 16:00 [PATCH v3 0/9] coresight: Fix and improve clock usage Leo Yan
@ 2025-06-09 16:00 ` Leo Yan
2025-06-09 16:00 ` [PATCH v3 2/9] coresight: catu: " Leo Yan
` (7 subsequent siblings)
8 siblings, 0 replies; 24+ messages in thread
From: Leo Yan @ 2025-06-09 16:00 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Anshuman Khandual,
Alexander Shishkin, Greg Kroah-Hartman
Cc: coresight, linux-arm-kernel, linux-kernel, Leo Yan
The atclk is an optional clock for the CoreSight TMC, but the driver
misses to initialize it. In most cases, TMC shares the atclk clock with
other CoreSight components. Since these components enable the clock
before the TMC device is initialized, the TMC continues properly,
which is why we don’t observe any lockup issues.
This change enables atclk in probe of the TMC driver. Given the clock
is optional, it is possible to return NULL if the clock does not exist.
IS_ERR() is tolerant for this case.
Dynamically disable and enable atclk during suspend and resume. The
clock pointers will never be error values if the driver has successfully
probed, and the case of a NULL pointer case will be handled by the clock
core layer. The driver data is always valid after probe. Therefore,
remove the related checks. Also in the resume flow adds error handling.
Fixes: bc4bf7fe98da ("coresight-tmc: add CoreSight TMC driver")
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
Signed-off-by: Leo Yan <leo.yan@arm.com>
---
drivers/hwtracing/coresight/coresight-tmc-core.c | 22 +++++++++++++++++-----
drivers/hwtracing/coresight/coresight-tmc.h | 2 ++
2 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index 88afb16bb6bec395ba535155228d176250f38625..0b5e7635a084d226619e69189a2ecbaff754ec43 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -789,6 +789,10 @@ static int __tmc_probe(struct device *dev, struct resource *res)
struct coresight_desc desc = { 0 };
struct coresight_dev_list *dev_list = NULL;
+ drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
+ if (IS_ERR(drvdata->atclk))
+ return PTR_ERR(drvdata->atclk);
+
ret = -ENOMEM;
/* Validity for the resource is already checked by the AMBA core */
@@ -1020,18 +1024,26 @@ static int tmc_runtime_suspend(struct device *dev)
{
struct tmc_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_disable_unprepare(drvdata->pclk);
+ 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;
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_prepare_enable(drvdata->pclk);
- return 0;
+ ret = clk_prepare_enable(drvdata->pclk);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(drvdata->atclk);
+ if (ret)
+ clk_disable_unprepare(drvdata->pclk);
+
+ return ret;
}
#endif
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index 6541a27a018e6c3da8685e2e1c93b228d44e66fc..cbb4ba43915855a8acbb9205167e87185c9a8c6c 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -210,6 +210,7 @@ struct tmc_resrv_buf {
/**
* struct tmc_drvdata - specifics associated to an TMC component
+ * @atclk: optional clock for the core parts of the TMC.
* @pclk: APB clock if present, otherwise NULL
* @base: memory mapped base address for this component.
* @csdev: component vitals needed by the framework.
@@ -244,6 +245,7 @@ struct tmc_resrv_buf {
* Used by ETR/ETF.
*/
struct tmc_drvdata {
+ struct clk *atclk;
struct clk *pclk;
void __iomem *base;
struct coresight_device *csdev;
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 2/9] coresight: catu: Support atclk
2025-06-09 16:00 [PATCH v3 0/9] coresight: Fix and improve clock usage Leo Yan
2025-06-09 16:00 ` [PATCH v3 1/9] coresight: tmc: Support atclk Leo Yan
@ 2025-06-09 16:00 ` Leo Yan
2025-06-09 16:00 ` [PATCH v3 3/9] coresight: etm4x: " Leo Yan
` (6 subsequent siblings)
8 siblings, 0 replies; 24+ messages in thread
From: Leo Yan @ 2025-06-09 16:00 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Anshuman Khandual,
Alexander Shishkin, Greg Kroah-Hartman
Cc: coresight, linux-arm-kernel, linux-kernel, Leo Yan
The atclk is an optional clock for the CoreSight CATU, but the driver
misses to initialize it.
This change enables atclk in probe of the CATU driver, and dynamically
control the clock during suspend and resume.
The checks for driver data and clocks in suspend and resume are not
needed, remove them. Add error handling in the resume function.
Fixes: fcacb5c154ba ("coresight: Introduce support for Coresight Address Translation Unit")
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
Signed-off-by: Leo Yan <leo.yan@arm.com>
---
drivers/hwtracing/coresight/coresight-catu.c | 22 +++++++++++++++++-----
drivers/hwtracing/coresight/coresight-catu.h | 1 +
2 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c
index 5058432233da1932f1965008fc1b98b560490414..af2a55f0c907c392d092a50612b23c115a1b0f5f 100644
--- a/drivers/hwtracing/coresight/coresight-catu.c
+++ b/drivers/hwtracing/coresight/coresight-catu.c
@@ -520,6 +520,10 @@ static int __catu_probe(struct device *dev, struct resource *res)
struct coresight_platform_data *pdata = NULL;
void __iomem *base;
+ drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
+ if (IS_ERR(drvdata->atclk))
+ return PTR_ERR(drvdata->atclk);
+
catu_desc.name = coresight_alloc_device_name(&catu_devs, dev);
if (!catu_desc.name)
return -ENOMEM;
@@ -668,18 +672,26 @@ static int catu_runtime_suspend(struct device *dev)
{
struct catu_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_disable_unprepare(drvdata->pclk);
+ 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;
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_prepare_enable(drvdata->pclk);
- return 0;
+ ret = clk_prepare_enable(drvdata->pclk);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(drvdata->atclk);
+ if (ret)
+ clk_disable_unprepare(drvdata->pclk);
+
+ return ret;
}
#endif
diff --git a/drivers/hwtracing/coresight/coresight-catu.h b/drivers/hwtracing/coresight/coresight-catu.h
index 755776cd19c5bb724845ca586ace1e0b29e72556..6e6b7aac206dcae9ff062355e50179637b4d1703 100644
--- a/drivers/hwtracing/coresight/coresight-catu.h
+++ b/drivers/hwtracing/coresight/coresight-catu.h
@@ -62,6 +62,7 @@
struct catu_drvdata {
struct clk *pclk;
+ struct clk *atclk;
void __iomem *base;
struct coresight_device *csdev;
int irq;
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 3/9] coresight: etm4x: Support atclk
2025-06-09 16:00 [PATCH v3 0/9] coresight: Fix and improve clock usage Leo Yan
2025-06-09 16:00 ` [PATCH v3 1/9] coresight: tmc: Support atclk Leo Yan
2025-06-09 16:00 ` [PATCH v3 2/9] coresight: catu: " Leo Yan
@ 2025-06-09 16:00 ` Leo Yan
2025-06-09 16:00 ` [PATCH v3 4/9] coresight: Appropriately disable programming clocks Leo Yan
` (5 subsequent siblings)
8 siblings, 0 replies; 24+ messages in thread
From: Leo Yan @ 2025-06-09 16:00 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Anshuman Khandual,
Alexander Shishkin, Greg Kroah-Hartman
Cc: coresight, linux-arm-kernel, linux-kernel, Leo Yan
The atclk is an optional clock for the CoreSight ETMv4, but the driver
misses to initialize it.
This change enables atclk in probe of the ETMv4 driver, and dynamically
control the clock during suspend and resume.
No need to check the driver data and clock pointer in the runtime
suspend and resume, so remove checks. And add error handling in the
resume function.
Add a minor fix to the comment format when adding the atclk field.
Fixes: 2e1cdfe184b5 ("coresight-etm4x: Adding CoreSight ETM4x driver")
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
Signed-off-by: Leo Yan <leo.yan@arm.com>
---
drivers/hwtracing/coresight/coresight-etm4x-core.c | 20 +++++++++++++++-----
drivers/hwtracing/coresight/coresight-etm4x.h | 4 +++-
2 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 42e5d37403addc6ec81f2e3184522d67d1677c04..205121c14d72ec2f6a193dccb94b7cfd5c314e26 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -2215,6 +2215,10 @@ static int etm4_probe(struct device *dev)
if (WARN_ON(!drvdata))
return -ENOMEM;
+ drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
+ if (IS_ERR(drvdata->atclk))
+ return PTR_ERR(drvdata->atclk);
+
if (pm_save_enable == PARAM_PM_SAVE_FIRMWARE)
pm_save_enable = coresight_loses_context_with_cpu(dev) ?
PARAM_PM_SAVE_SELF_HOSTED : PARAM_PM_SAVE_NEVER;
@@ -2463,8 +2467,8 @@ static int etm4_runtime_suspend(struct device *dev)
{
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata->pclk && !IS_ERR(drvdata->pclk))
- clk_disable_unprepare(drvdata->pclk);
+ clk_disable_unprepare(drvdata->atclk);
+ clk_disable_unprepare(drvdata->pclk);
return 0;
}
@@ -2472,11 +2476,17 @@ static int etm4_runtime_suspend(struct device *dev)
static int etm4_runtime_resume(struct device *dev)
{
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(drvdata->pclk);
+ if (ret)
+ return ret;
- if (drvdata->pclk && !IS_ERR(drvdata->pclk))
- clk_prepare_enable(drvdata->pclk);
+ ret = clk_prepare_enable(drvdata->atclk);
+ if (ret)
+ clk_disable_unprepare(drvdata->pclk);
- return 0;
+ return ret;
}
#endif
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
index ac649515054d905fa365203bd35f1d839b03292f..96c14ec26893a489a96c7acfe9ba308e0e890917 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.h
+++ b/drivers/hwtracing/coresight/coresight-etm4x.h
@@ -919,7 +919,8 @@ struct etmv4_save_state {
/**
* struct etm4_drvdata - specifics associated to an ETM component
- * @pclk APB clock if present, otherwise NULL
+ * @pclk: APB clock if present, otherwise NULL
+ * @atclk: Optional clock for the core parts of the ETMv4.
* @base: Memory mapped base address for this component.
* @csdev: Component vitals needed by the framework.
* @spinlock: Only one at a time pls.
@@ -988,6 +989,7 @@ struct etmv4_save_state {
*/
struct etmv4_drvdata {
struct clk *pclk;
+ struct clk *atclk;
void __iomem *base;
struct coresight_device *csdev;
raw_spinlock_t spinlock;
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 4/9] coresight: Appropriately disable programming clocks
2025-06-09 16:00 [PATCH v3 0/9] coresight: Fix and improve clock usage Leo Yan
` (2 preceding siblings ...)
2025-06-09 16:00 ` [PATCH v3 3/9] coresight: etm4x: " Leo Yan
@ 2025-06-09 16:00 ` Leo Yan
2025-06-09 16:11 ` Suzuki K Poulose
2025-06-24 4:37 ` Anshuman Khandual
2025-06-09 16:00 ` [PATCH v3 5/9] coresight: Appropriately disable trace bus clocks Leo Yan
` (4 subsequent siblings)
8 siblings, 2 replies; 24+ messages in thread
From: Leo Yan @ 2025-06-09 16:00 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Anshuman Khandual,
Alexander Shishkin, Greg Kroah-Hartman
Cc: coresight, linux-arm-kernel, linux-kernel, Leo Yan
Some CoreSight components have programming clocks (pclk) and are enabled
using clk_get() and clk_prepare_enable(). However, in many cases, these
clocks are not disabled when modules exit and only released by clk_put().
To fix the issue, this commit refactors coresight_get_enable_apb_pclk()
by replacing clk_get() and clk_prepare_enable() with
devm_clk_get_enabled() for enabling APB clock. Callers are updated
to reuse the returned error value.
With the change, programming clocks are managed as resources in driver
model layer, allowing clock cleanup to be handled automatically. As a
result, manual cleanup operations are no longer needed and are removed
from the Coresight drivers.
Fixes: 73d779a03a76 ("coresight: etm4x: Change etm4_platform_driver driver for MMIO devices")
Signed-off-by: Leo Yan <leo.yan@arm.com>
---
drivers/hwtracing/coresight/coresight-catu.c | 9 ++-------
drivers/hwtracing/coresight/coresight-cpu-debug.c | 6 +-----
drivers/hwtracing/coresight/coresight-ctcu-core.c | 10 ++--------
drivers/hwtracing/coresight/coresight-etm4x-core.c | 9 ++-------
drivers/hwtracing/coresight/coresight-funnel.c | 6 +-----
drivers/hwtracing/coresight/coresight-replicator.c | 6 +-----
drivers/hwtracing/coresight/coresight-stm.c | 4 +---
drivers/hwtracing/coresight/coresight-tmc-core.c | 4 +---
drivers/hwtracing/coresight/coresight-tpiu.c | 4 +---
include/linux/coresight.h | 16 +++-------------
10 files changed, 15 insertions(+), 59 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c
index af2a55f0c907c392d092a50612b23c115a1b0f5f..4c345ff2cff141ea63c2220393e5fdd00c449ca6 100644
--- a/drivers/hwtracing/coresight/coresight-catu.c
+++ b/drivers/hwtracing/coresight/coresight-catu.c
@@ -636,7 +636,7 @@ static int catu_platform_probe(struct platform_device *pdev)
drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
if (IS_ERR(drvdata->pclk))
- return -ENODEV;
+ return PTR_ERR(drvdata->pclk);
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
@@ -645,11 +645,8 @@ static int catu_platform_probe(struct platform_device *pdev)
dev_set_drvdata(&pdev->dev, drvdata);
ret = __catu_probe(&pdev->dev, res);
pm_runtime_put(&pdev->dev);
- if (ret) {
+ if (ret)
pm_runtime_disable(&pdev->dev);
- if (!IS_ERR_OR_NULL(drvdata->pclk))
- clk_put(drvdata->pclk);
- }
return ret;
}
@@ -663,8 +660,6 @@ static void catu_platform_remove(struct platform_device *pdev)
__catu_remove(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- if (!IS_ERR_OR_NULL(drvdata->pclk))
- clk_put(drvdata->pclk);
}
#ifdef CONFIG_PM
diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c
index a871d997330b09bdb741f35c59108b0b3252cc54..e39dfb886688e111eee95d4294f37fa85baccd14 100644
--- a/drivers/hwtracing/coresight/coresight-cpu-debug.c
+++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c
@@ -699,7 +699,7 @@ static int debug_platform_probe(struct platform_device *pdev)
drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
if (IS_ERR(drvdata->pclk))
- return -ENODEV;
+ return PTR_ERR(drvdata->pclk);
dev_set_drvdata(&pdev->dev, drvdata);
pm_runtime_get_noresume(&pdev->dev);
@@ -710,8 +710,6 @@ static int debug_platform_probe(struct platform_device *pdev)
if (ret) {
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- if (!IS_ERR_OR_NULL(drvdata->pclk))
- clk_put(drvdata->pclk);
}
return ret;
}
@@ -725,8 +723,6 @@ static void debug_platform_remove(struct platform_device *pdev)
__debug_remove(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- if (!IS_ERR_OR_NULL(drvdata->pclk))
- clk_put(drvdata->pclk);
}
#ifdef CONFIG_ACPI
diff --git a/drivers/hwtracing/coresight/coresight-ctcu-core.c b/drivers/hwtracing/coresight/coresight-ctcu-core.c
index c6bafc96db963310b5e77a095953c83a172cfc7c..de279efe340581ceabfb9e1cd1e7fe4b5e4f826e 100644
--- a/drivers/hwtracing/coresight/coresight-ctcu-core.c
+++ b/drivers/hwtracing/coresight/coresight-ctcu-core.c
@@ -209,7 +209,7 @@ static int ctcu_probe(struct platform_device *pdev)
drvdata->apb_clk = coresight_get_enable_apb_pclk(dev);
if (IS_ERR(drvdata->apb_clk))
- return -ENODEV;
+ return PTR_ERR(drvdata->apb_clk);
cfgs = of_device_get_match_data(dev);
if (cfgs) {
@@ -233,12 +233,8 @@ static int ctcu_probe(struct platform_device *pdev)
desc.access = CSDEV_ACCESS_IOMEM(base);
drvdata->csdev = coresight_register(&desc);
- if (IS_ERR(drvdata->csdev)) {
- if (!IS_ERR_OR_NULL(drvdata->apb_clk))
- clk_put(drvdata->apb_clk);
-
+ if (IS_ERR(drvdata->csdev))
return PTR_ERR(drvdata->csdev);
- }
return 0;
}
@@ -275,8 +271,6 @@ static void ctcu_platform_remove(struct platform_device *pdev)
ctcu_remove(pdev);
pm_runtime_disable(&pdev->dev);
- if (!IS_ERR_OR_NULL(drvdata->apb_clk))
- clk_put(drvdata->apb_clk);
}
#ifdef CONFIG_PM
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 205121c14d72ec2f6a193dccb94b7cfd5c314e26..1915da95b93d953a61778a71b4880c87b91fe17a 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -2303,14 +2303,12 @@ static int etm4_probe_platform_dev(struct platform_device *pdev)
drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
if (IS_ERR(drvdata->pclk))
- return -ENODEV;
+ return PTR_ERR(drvdata->pclk);
if (res) {
drvdata->base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(drvdata->base)) {
- clk_put(drvdata->pclk);
+ if (IS_ERR(drvdata->base))
return PTR_ERR(drvdata->base);
- }
}
dev_set_drvdata(&pdev->dev, drvdata);
@@ -2417,9 +2415,6 @@ static void etm4_remove_platform_dev(struct platform_device *pdev)
if (drvdata)
etm4_remove_dev(drvdata);
pm_runtime_disable(&pdev->dev);
-
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_put(drvdata->pclk);
}
static const struct amba_id etm4_ids[] = {
diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
index b1922dbe9292b02c91ca5730998e59ecdb08fdc7..36fc4e991458c112521c4261d73f3e58e9a3f995 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -240,7 +240,7 @@ static int funnel_probe(struct device *dev, struct resource *res)
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
if (IS_ERR(drvdata->pclk))
- return -ENODEV;
+ return PTR_ERR(drvdata->pclk);
/*
* Map the device base for dynamic-funnel, which has been
@@ -284,8 +284,6 @@ static int funnel_probe(struct device *dev, struct resource *res)
out_disable_clk:
if (ret && !IS_ERR_OR_NULL(drvdata->atclk))
clk_disable_unprepare(drvdata->atclk);
- if (ret && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_disable_unprepare(drvdata->pclk);
return ret;
}
@@ -355,8 +353,6 @@ static void funnel_platform_remove(struct platform_device *pdev)
funnel_remove(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- if (!IS_ERR_OR_NULL(drvdata->pclk))
- clk_put(drvdata->pclk);
}
static const struct of_device_id funnel_match[] = {
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
index 06efd2b01a0f71620eac71166567d14655b58403..6dd24eb10a94b0eb28f4f27afab845227e22b96c 100644
--- a/drivers/hwtracing/coresight/coresight-replicator.c
+++ b/drivers/hwtracing/coresight/coresight-replicator.c
@@ -247,7 +247,7 @@ static int replicator_probe(struct device *dev, struct resource *res)
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
if (IS_ERR(drvdata->pclk))
- return -ENODEV;
+ return PTR_ERR(drvdata->pclk);
/*
* Map the device base for dynamic-replicator, which has been
@@ -296,8 +296,6 @@ static int replicator_probe(struct device *dev, struct resource *res)
out_disable_clk:
if (ret && !IS_ERR_OR_NULL(drvdata->atclk))
clk_disable_unprepare(drvdata->atclk);
- if (ret && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_disable_unprepare(drvdata->pclk);
return ret;
}
@@ -335,8 +333,6 @@ static void replicator_platform_remove(struct platform_device *pdev)
replicator_remove(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- if (!IS_ERR_OR_NULL(drvdata->pclk))
- clk_put(drvdata->pclk);
}
#ifdef CONFIG_PM
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index e45c6c7204b4491e0f879bc7d5d445aa1d3118be..88ee453b2815444a550a2b932b28367eb93336b8 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -851,7 +851,7 @@ static int __stm_probe(struct device *dev, struct resource *res)
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
if (IS_ERR(drvdata->pclk))
- return -ENODEV;
+ return PTR_ERR(drvdata->pclk);
dev_set_drvdata(dev, drvdata);
base = devm_ioremap_resource(dev, res);
@@ -1033,8 +1033,6 @@ static void stm_platform_remove(struct platform_device *pdev)
__stm_remove(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- if (!IS_ERR_OR_NULL(drvdata->pclk))
- clk_put(drvdata->pclk);
}
#ifdef CONFIG_ACPI
diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index 0b5e7635a084d226619e69189a2ecbaff754ec43..e867198b03e82892da7312c9dc1c69676602c598 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -991,7 +991,7 @@ static int tmc_platform_probe(struct platform_device *pdev)
drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
if (IS_ERR(drvdata->pclk))
- return -ENODEV;
+ return PTR_ERR(drvdata->pclk);
dev_set_drvdata(&pdev->dev, drvdata);
pm_runtime_get_noresume(&pdev->dev);
@@ -1015,8 +1015,6 @@ static void tmc_platform_remove(struct platform_device *pdev)
__tmc_remove(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- if (!IS_ERR_OR_NULL(drvdata->pclk))
- clk_put(drvdata->pclk);
}
#ifdef CONFIG_PM
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
index 3e01592884280819c16398cbb5e09cbaee5d3efb..b2559c6fac6d2f02e0038e583cd324d7165c5aee 100644
--- a/drivers/hwtracing/coresight/coresight-tpiu.c
+++ b/drivers/hwtracing/coresight/coresight-tpiu.c
@@ -153,7 +153,7 @@ static int __tpiu_probe(struct device *dev, struct resource *res)
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
if (IS_ERR(drvdata->pclk))
- return -ENODEV;
+ return PTR_ERR(drvdata->pclk);
dev_set_drvdata(dev, drvdata);
/* Validity for the resource is already checked by the AMBA core */
@@ -293,8 +293,6 @@ static void tpiu_platform_remove(struct platform_device *pdev)
__tpiu_remove(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- if (!IS_ERR_OR_NULL(drvdata->pclk))
- clk_put(drvdata->pclk);
}
#ifdef CONFIG_ACPI
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 4ac65c68bbf44b98db22c3dad2d83a224ce5278e..dd2b4cc7a2b70cf060a3207548fe80e3824c489f 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -480,26 +480,16 @@ static inline bool is_coresight_device(void __iomem *base)
* Returns:
*
* clk - Clock is found and enabled
- * NULL - clock is not found
* ERROR - Clock is found but failed to enable
*/
static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev)
{
struct clk *pclk;
- int ret;
- pclk = clk_get(dev, "apb_pclk");
- if (IS_ERR(pclk)) {
- pclk = clk_get(dev, "apb");
- if (IS_ERR(pclk))
- return NULL;
- }
+ pclk = devm_clk_get_enabled(dev, "apb_pclk");
+ if (IS_ERR(pclk))
+ pclk = devm_clk_get_enabled(dev, "apb");
- ret = clk_prepare_enable(pclk);
- if (ret) {
- clk_put(pclk);
- return ERR_PTR(ret);
- }
return pclk;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 5/9] coresight: Appropriately disable trace bus clocks
2025-06-09 16:00 [PATCH v3 0/9] coresight: Fix and improve clock usage Leo Yan
` (3 preceding siblings ...)
2025-06-09 16:00 ` [PATCH v3 4/9] coresight: Appropriately disable programming clocks Leo Yan
@ 2025-06-09 16:00 ` Leo Yan
[not found] ` <89f9fede-3a0f-4ed6-a42d-43827f7a4fca@arm.com>
2025-06-09 16:00 ` [PATCH v3 6/9] coresight: Avoid enable programming clock duplicately Leo Yan
` (3 subsequent siblings)
8 siblings, 1 reply; 24+ messages in thread
From: Leo Yan @ 2025-06-09 16:00 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Anshuman Khandual,
Alexander Shishkin, Greg Kroah-Hartman
Cc: coresight, linux-arm-kernel, linux-kernel, Leo Yan
Some CoreSight components have trace bus clocks 'atclk' and are enabled
using clk_prepare_enable(). These clocks are not disabled when modules
exit.
As atclk is optional, use devm_clk_get_optional_enabled() to manage it.
The benefit is the driver model layer can automatically disable and
release clocks.
Check the returned value with IS_ERR() to detect errors but leave the
NULL pointer case if the clock is not found. And remove the error
handling codes which are no longer needed.
Fixes: d1839e687773 ("coresight: etm: retrieve and handle atclk")
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
Signed-off-by: Leo Yan <leo.yan@arm.com>
---
drivers/hwtracing/coresight/coresight-etb10.c | 10 +++---
drivers/hwtracing/coresight/coresight-etm3x-core.c | 9 ++----
drivers/hwtracing/coresight/coresight-funnel.c | 36 +++++++---------------
drivers/hwtracing/coresight/coresight-replicator.c | 34 ++++++--------------
drivers/hwtracing/coresight/coresight-stm.c | 9 ++----
drivers/hwtracing/coresight/coresight-tpiu.c | 10 ++----
6 files changed, 34 insertions(+), 74 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index d5efb085b30d36b51ca591c1b595ef82481f5569..8e81b41eb22264f17606050fa8da277aae05c5cc 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -730,12 +730,10 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id)
if (!drvdata)
return -ENOMEM;
- drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */
- if (!IS_ERR(drvdata->atclk)) {
- ret = clk_prepare_enable(drvdata->atclk);
- if (ret)
- return ret;
- }
+ drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
+ if (IS_ERR(drvdata->atclk))
+ return PTR_ERR(drvdata->atclk);
+
dev_set_drvdata(dev, drvdata);
/* validity for the resource is already checked by the AMBA core */
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c
index 1c6204e1442211be6f3d7ca34bd2251ba796601b..baba2245b1dfb31f4bf19080e20c33df3a5b854f 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c
@@ -832,12 +832,9 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id)
spin_lock_init(&drvdata->spinlock);
- drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */
- if (!IS_ERR(drvdata->atclk)) {
- ret = clk_prepare_enable(drvdata->atclk);
- if (ret)
- return ret;
- }
+ drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
+ if (IS_ERR(drvdata->atclk))
+ return PTR_ERR(drvdata->atclk);
drvdata->cpu = coresight_get_cpu(dev);
if (drvdata->cpu < 0)
diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
index 36fc4e991458c112521c4261d73f3e58e9a3f995..b044a4125310ba4f8c88df295ec3684ab266682f 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -213,7 +213,6 @@ ATTRIBUTE_GROUPS(coresight_funnel);
static int funnel_probe(struct device *dev, struct resource *res)
{
- int ret;
void __iomem *base;
struct coresight_platform_data *pdata = NULL;
struct funnel_drvdata *drvdata;
@@ -231,12 +230,9 @@ static int funnel_probe(struct device *dev, struct resource *res)
if (!drvdata)
return -ENOMEM;
- drvdata->atclk = devm_clk_get(dev, "atclk"); /* optional */
- if (!IS_ERR(drvdata->atclk)) {
- ret = clk_prepare_enable(drvdata->atclk);
- if (ret)
- return ret;
- }
+ drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
+ if (IS_ERR(drvdata->atclk))
+ return PTR_ERR(drvdata->atclk);
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
if (IS_ERR(drvdata->pclk))
@@ -248,10 +244,8 @@ static int funnel_probe(struct device *dev, struct resource *res)
*/
if (res) {
base = devm_ioremap_resource(dev, res);
- if (IS_ERR(base)) {
- ret = PTR_ERR(base);
- goto out_disable_clk;
- }
+ if (IS_ERR(base))
+ return PTR_ERR(base);
drvdata->base = base;
desc.groups = coresight_funnel_groups;
desc.access = CSDEV_ACCESS_IOMEM(base);
@@ -261,10 +255,9 @@ static int funnel_probe(struct device *dev, struct resource *res)
dev_set_drvdata(dev, drvdata);
pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata)) {
- ret = PTR_ERR(pdata);
- goto out_disable_clk;
- }
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
+
dev->platform_data = pdata;
raw_spin_lock_init(&drvdata->spinlock);
@@ -274,17 +267,10 @@ static int funnel_probe(struct device *dev, struct resource *res)
desc.pdata = pdata;
desc.dev = dev;
drvdata->csdev = coresight_register(&desc);
- if (IS_ERR(drvdata->csdev)) {
- ret = PTR_ERR(drvdata->csdev);
- goto out_disable_clk;
- }
+ if (IS_ERR(drvdata->csdev))
+ return PTR_ERR(drvdata->csdev);
- ret = 0;
-
-out_disable_clk:
- if (ret && !IS_ERR_OR_NULL(drvdata->atclk))
- clk_disable_unprepare(drvdata->atclk);
- return ret;
+ return 0;
}
static int funnel_remove(struct device *dev)
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
index 6dd24eb10a94b0eb28f4f27afab845227e22b96c..9e8bd36e7a9a2fd061f41c56242ac2b11549daf5 100644
--- a/drivers/hwtracing/coresight/coresight-replicator.c
+++ b/drivers/hwtracing/coresight/coresight-replicator.c
@@ -219,7 +219,6 @@ static const struct attribute_group *replicator_groups[] = {
static int replicator_probe(struct device *dev, struct resource *res)
{
- int ret = 0;
struct coresight_platform_data *pdata = NULL;
struct replicator_drvdata *drvdata;
struct coresight_desc desc = { 0 };
@@ -238,12 +237,9 @@ static int replicator_probe(struct device *dev, struct resource *res)
if (!drvdata)
return -ENOMEM;
- drvdata->atclk = devm_clk_get(dev, "atclk"); /* optional */
- if (!IS_ERR(drvdata->atclk)) {
- ret = clk_prepare_enable(drvdata->atclk);
- if (ret)
- return ret;
- }
+ drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
+ if (IS_ERR(drvdata->atclk))
+ return PTR_ERR(drvdata->atclk);
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
if (IS_ERR(drvdata->pclk))
@@ -255,10 +251,8 @@ static int replicator_probe(struct device *dev, struct resource *res)
*/
if (res) {
base = devm_ioremap_resource(dev, res);
- if (IS_ERR(base)) {
- ret = PTR_ERR(base);
- goto out_disable_clk;
- }
+ if (IS_ERR(base))
+ return PTR_ERR(base);
drvdata->base = base;
desc.groups = replicator_groups;
desc.access = CSDEV_ACCESS_IOMEM(base);
@@ -272,10 +266,8 @@ static int replicator_probe(struct device *dev, struct resource *res)
dev_set_drvdata(dev, drvdata);
pdata = coresight_get_platform_data(dev);
- if (IS_ERR(pdata)) {
- ret = PTR_ERR(pdata);
- goto out_disable_clk;
- }
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
dev->platform_data = pdata;
raw_spin_lock_init(&drvdata->spinlock);
@@ -286,17 +278,11 @@ static int replicator_probe(struct device *dev, struct resource *res)
desc.dev = dev;
drvdata->csdev = coresight_register(&desc);
- if (IS_ERR(drvdata->csdev)) {
- ret = PTR_ERR(drvdata->csdev);
- goto out_disable_clk;
- }
+ if (IS_ERR(drvdata->csdev))
+ return PTR_ERR(drvdata->csdev);
replicator_reset(drvdata);
-
-out_disable_clk:
- if (ret && !IS_ERR_OR_NULL(drvdata->atclk))
- clk_disable_unprepare(drvdata->atclk);
- return ret;
+ return 0;
}
static int replicator_remove(struct device *dev)
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index 88ee453b2815444a550a2b932b28367eb93336b8..57fbe3ad0fb20501d4e7e5c478d1e56e98685c40 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -842,12 +842,9 @@ static int __stm_probe(struct device *dev, struct resource *res)
if (!drvdata)
return -ENOMEM;
- drvdata->atclk = devm_clk_get(dev, "atclk"); /* optional */
- if (!IS_ERR(drvdata->atclk)) {
- ret = clk_prepare_enable(drvdata->atclk);
- if (ret)
- return ret;
- }
+ drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
+ if (IS_ERR(drvdata->atclk))
+ return PTR_ERR(drvdata->atclk);
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
if (IS_ERR(drvdata->pclk))
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
index b2559c6fac6d2f02e0038e583cd324d7165c5aee..8d6179c83e5d3194d1f90e10c88fcc1faccf0cd7 100644
--- a/drivers/hwtracing/coresight/coresight-tpiu.c
+++ b/drivers/hwtracing/coresight/coresight-tpiu.c
@@ -128,7 +128,6 @@ static const struct coresight_ops tpiu_cs_ops = {
static int __tpiu_probe(struct device *dev, struct resource *res)
{
- int ret;
void __iomem *base;
struct coresight_platform_data *pdata = NULL;
struct tpiu_drvdata *drvdata;
@@ -144,12 +143,9 @@ static int __tpiu_probe(struct device *dev, struct resource *res)
spin_lock_init(&drvdata->spinlock);
- drvdata->atclk = devm_clk_get(dev, "atclk"); /* optional */
- if (!IS_ERR(drvdata->atclk)) {
- ret = clk_prepare_enable(drvdata->atclk);
- if (ret)
- return ret;
- }
+ drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
+ if (IS_ERR(drvdata->atclk))
+ return PTR_ERR(drvdata->atclk);
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
if (IS_ERR(drvdata->pclk))
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 6/9] coresight: Avoid enable programming clock duplicately
2025-06-09 16:00 [PATCH v3 0/9] coresight: Fix and improve clock usage Leo Yan
` (4 preceding siblings ...)
2025-06-09 16:00 ` [PATCH v3 5/9] coresight: Appropriately disable trace bus clocks Leo Yan
@ 2025-06-09 16:00 ` Leo Yan
2025-06-09 16:58 ` Suzuki K Poulose
2025-06-24 5:11 ` Anshuman Khandual
2025-06-09 16:00 ` [PATCH v3 7/9] coresight: Consolidate clock enabling Leo Yan
` (2 subsequent siblings)
8 siblings, 2 replies; 24+ messages in thread
From: Leo Yan @ 2025-06-09 16:00 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Anshuman Khandual,
Alexander Shishkin, Greg Kroah-Hartman
Cc: coresight, linux-arm-kernel, linux-kernel, Leo Yan
The programming clock is enabled by AMBA bus driver before a dynamic
probe. As a result, a CoreSight driver may redundantly enable the same
clock.
To avoid this, add a check for device type and skip enabling the
programming clock for AMBA devices. The returned NULL pointer will be
tolerated by the drivers.
Fixes: 73d779a03a76 ("coresight: etm4x: Change etm4_platform_driver driver for MMIO devices")
Signed-off-by: Leo Yan <leo.yan@arm.com>
---
include/linux/coresight.h | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index dd2b4cc7a2b70cf060a3207548fe80e3824c489f..9afa1f76c78a3347e54d94fe9a9ebed72e3fff8e 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -480,15 +480,18 @@ static inline bool is_coresight_device(void __iomem *base)
* Returns:
*
* clk - Clock is found and enabled
+ * NULL - Clock is not needed as it is managed by the AMBA bus driver
* ERROR - Clock is found but failed to enable
*/
static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev)
{
- struct clk *pclk;
+ struct clk *pclk = NULL;
- pclk = devm_clk_get_enabled(dev, "apb_pclk");
- if (IS_ERR(pclk))
- pclk = devm_clk_get_enabled(dev, "apb");
+ if (!dev_is_amba(dev)) {
+ pclk = devm_clk_get_enabled(dev, "apb_pclk");
+ if (IS_ERR(pclk))
+ pclk = devm_clk_get_enabled(dev, "apb");
+ }
return pclk;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 7/9] coresight: Consolidate clock enabling
2025-06-09 16:00 [PATCH v3 0/9] coresight: Fix and improve clock usage Leo Yan
` (5 preceding siblings ...)
2025-06-09 16:00 ` [PATCH v3 6/9] coresight: Avoid enable programming clock duplicately Leo Yan
@ 2025-06-09 16:00 ` Leo Yan
2025-06-24 5:44 ` Anshuman Khandual
2025-06-09 16:00 ` [PATCH v3 8/9] coresight: Make clock sequence consistent Leo Yan
2025-06-09 16:00 ` [PATCH v3 9/9] coresight: Refactor runtime PM Leo Yan
8 siblings, 1 reply; 24+ messages in thread
From: Leo Yan @ 2025-06-09 16:00 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Anshuman Khandual,
Alexander Shishkin, Greg Kroah-Hartman
Cc: coresight, linux-arm-kernel, linux-kernel, Leo Yan
CoreSight drivers enable pclk and atclk conditionally. For example,
pclk is only enabled in the static probe, while atclk is an optional
clock that it is enabled for both dynamic and static probes, if it is
present. In the current CoreSight drivers, these two clocks are
initialized separately. This causes complex and duplicate codes.
This patch consolidates clock enabling into a central place. It renames
coresight_get_enable_apb_pclk() to coresight_get_enable_clocks() and
encapsulates clock initialization logic:
- If a clock is initialized successfully, its clock pointer is assigned
to the double pointer passed as an argument.
- If pclk is skipped for an AMBA device, or if atclk is not found, the
corresponding double pointer is set to NULL. The function returns
Success (0) to guide callers can proceed with no error.
- Otherwise, an error number is returned for failures.
The function became complex, move it from the header to the CoreSight
core layer and the symbol is exported. Added comments for recording
details.
CoreSight drivers are refined so that clocks are initialized in one go.
As a result, driver data no longer needs to be allocated separately in
the static and dynamic probes. Moved the allocation into a low-level
function to avoid code duplication.
Suggested-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Leo Yan <leo.yan@arm.com>
---
drivers/hwtracing/coresight/coresight-catu.c | 30 +++++----------
drivers/hwtracing/coresight/coresight-core.c | 45 ++++++++++++++++++++++
drivers/hwtracing/coresight/coresight-cpu-debug.c | 29 ++++++--------
drivers/hwtracing/coresight/coresight-ctcu-core.c | 8 ++--
drivers/hwtracing/coresight/coresight-etm4x-core.c | 11 ++----
drivers/hwtracing/coresight/coresight-funnel.c | 11 ++----
drivers/hwtracing/coresight/coresight-replicator.c | 11 ++----
drivers/hwtracing/coresight/coresight-stm.c | 9 ++---
drivers/hwtracing/coresight/coresight-tmc-core.c | 30 +++++----------
drivers/hwtracing/coresight/coresight-tpiu.c | 10 ++---
include/linux/coresight.h | 23 +----------
11 files changed, 101 insertions(+), 116 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c
index 4c345ff2cff141ea63c2220393e5fdd00c449ca6..a3ccb7034ae14d7339bc2549bccadf11e28c45e2 100644
--- a/drivers/hwtracing/coresight/coresight-catu.c
+++ b/drivers/hwtracing/coresight/coresight-catu.c
@@ -515,14 +515,20 @@ static int __catu_probe(struct device *dev, struct resource *res)
{
int ret = 0;
u32 dma_mask;
- struct catu_drvdata *drvdata = dev_get_drvdata(dev);
+ struct catu_drvdata *drvdata;
struct coresight_desc catu_desc;
struct coresight_platform_data *pdata = NULL;
void __iomem *base;
- drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
- if (IS_ERR(drvdata->atclk))
- return PTR_ERR(drvdata->atclk);
+ drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+ if (!drvdata)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev, drvdata);
+
+ ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk);
+ if (ret)
+ return ret;
catu_desc.name = coresight_alloc_device_name(&catu_devs, dev);
if (!catu_desc.name)
@@ -580,14 +586,8 @@ static int __catu_probe(struct device *dev, struct resource *res)
static int catu_probe(struct amba_device *adev, const struct amba_id *id)
{
- struct catu_drvdata *drvdata;
int ret;
- drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL);
- if (!drvdata)
- return -ENOMEM;
-
- amba_set_drvdata(adev, drvdata);
ret = __catu_probe(&adev->dev, &adev->res);
if (!ret)
pm_runtime_put(&adev->dev);
@@ -627,22 +627,12 @@ static struct amba_driver catu_driver = {
static int catu_platform_probe(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- struct catu_drvdata *drvdata;
int ret = 0;
- drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
- if (!drvdata)
- return -ENOMEM;
-
- drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
- if (IS_ERR(drvdata->pclk))
- return PTR_ERR(drvdata->pclk);
-
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
- dev_set_drvdata(&pdev->dev, drvdata);
ret = __catu_probe(&pdev->dev, res);
pm_runtime_put(&pdev->dev);
if (ret)
diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index fa758cc21827552a5c97b6bdd05d22dec4994b22..f9cc240e7c259fdb7cb3ee321825b44079a07b69 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -1698,6 +1698,51 @@ int coresight_etm_get_trace_id(struct coresight_device *csdev, enum cs_mode mode
}
EXPORT_SYMBOL_GPL(coresight_etm_get_trace_id);
+/*
+ * Attempt to find and enable programming clock (pclk) and trace clock (atclk)
+ * for the given device.
+ *
+ * The AMBA bus driver will cover the pclk, to avoid duplicate operations,
+ * skip to get and enable the pclk for an AMBA device.
+ *
+ * atclk is an optional clock, it will be only enabled when it is existed.
+ * Otherwise, a NULL pointer will be returned to caller.
+ *
+ * Returns: '0' on Success; Error code otherwise.
+ */
+int coresight_get_enable_clocks(struct device *dev, struct clk **pclk,
+ struct clk **atclk)
+{
+ WARN_ON(!pclk);
+
+ if (dev_is_amba(dev)) {
+ /* Don't enable pclk for an AMBA device */
+ *pclk = NULL;
+ } else {
+ /*
+ * "apb_pclk" is the default clock name for an Arm Primecell
+ * peripheral, while "apb" is used only by the CTCU driver.
+ *
+ * For easier maintenance, CoreSight drivers should use
+ * "apb_pclk" as the programming clock name.
+ */
+ *pclk = devm_clk_get_enabled(dev, "apb_pclk");
+ if (IS_ERR(*pclk))
+ *pclk = devm_clk_get_enabled(dev, "apb");
+ if (IS_ERR(*pclk))
+ return PTR_ERR(*pclk);
+ }
+
+ if (atclk) {
+ *atclk = devm_clk_get_optional_enabled(dev, "atclk");
+ if (IS_ERR(*atclk))
+ return PTR_ERR(*atclk);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(coresight_get_enable_clocks);
+
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c
index e39dfb886688e111eee95d4294f37fa85baccd14..3edfb5d3d02056afcaab4da575d1101c68aeac80 100644
--- a/drivers/hwtracing/coresight/coresight-cpu-debug.c
+++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c
@@ -562,10 +562,20 @@ static void debug_func_exit(void)
static int __debug_probe(struct device *dev, struct resource *res)
{
- struct debug_drvdata *drvdata = dev_get_drvdata(dev);
+ struct debug_drvdata *drvdata;
void __iomem *base;
int ret;
+ drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+ if (!drvdata)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev, drvdata);
+
+ ret = coresight_get_enable_clocks(dev, &drvdata->pclk, NULL);
+ if (ret)
+ return ret;
+
drvdata->cpu = coresight_get_cpu(dev);
if (drvdata->cpu < 0)
return drvdata->cpu;
@@ -625,13 +635,6 @@ static int __debug_probe(struct device *dev, struct resource *res)
static int debug_probe(struct amba_device *adev, const struct amba_id *id)
{
- struct debug_drvdata *drvdata;
-
- drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL);
- if (!drvdata)
- return -ENOMEM;
-
- amba_set_drvdata(adev, drvdata);
return __debug_probe(&adev->dev, &adev->res);
}
@@ -690,18 +693,8 @@ static struct amba_driver debug_driver = {
static int debug_platform_probe(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- struct debug_drvdata *drvdata;
int ret = 0;
- drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
- if (!drvdata)
- return -ENOMEM;
-
- drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
- if (IS_ERR(drvdata->pclk))
- return PTR_ERR(drvdata->pclk);
-
- dev_set_drvdata(&pdev->dev, drvdata);
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
diff --git a/drivers/hwtracing/coresight/coresight-ctcu-core.c b/drivers/hwtracing/coresight/coresight-ctcu-core.c
index de279efe340581ceabfb9e1cd1e7fe4b5e4f826e..75b5114ef652e4a47c53fbd2b7811c1bab575645 100644
--- a/drivers/hwtracing/coresight/coresight-ctcu-core.c
+++ b/drivers/hwtracing/coresight/coresight-ctcu-core.c
@@ -188,7 +188,7 @@ static int ctcu_probe(struct platform_device *pdev)
const struct ctcu_config *cfgs;
struct ctcu_drvdata *drvdata;
void __iomem *base;
- int i;
+ int i, ret;
desc.name = coresight_alloc_device_name(&ctcu_devs, dev);
if (!desc.name)
@@ -207,9 +207,9 @@ static int ctcu_probe(struct platform_device *pdev)
if (IS_ERR(base))
return PTR_ERR(base);
- drvdata->apb_clk = coresight_get_enable_apb_pclk(dev);
- if (IS_ERR(drvdata->apb_clk))
- return PTR_ERR(drvdata->apb_clk);
+ ret = coresight_get_enable_clocks(dev, &drvdata->apb_clk, NULL);
+ if (ret)
+ return ret;
cfgs = of_device_get_match_data(dev);
if (cfgs) {
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 1915da95b93d953a61778a71b4880c87b91fe17a..a742466ad0e14d2ceeeccddec5bba4f2160793c2 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -2211,13 +2211,14 @@ static int etm4_probe(struct device *dev)
struct csdev_access access = { 0 };
struct etm4_init_arg init_arg = { 0 };
struct etm4_init_arg *delayed;
+ int ret;
if (WARN_ON(!drvdata))
return -ENOMEM;
- drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
- if (IS_ERR(drvdata->atclk))
- return PTR_ERR(drvdata->atclk);
+ ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk);
+ if (ret)
+ return ret;
if (pm_save_enable == PARAM_PM_SAVE_FIRMWARE)
pm_save_enable = coresight_loses_context_with_cpu(dev) ?
@@ -2301,10 +2302,6 @@ static int etm4_probe_platform_dev(struct platform_device *pdev)
if (!drvdata)
return -ENOMEM;
- drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
- if (IS_ERR(drvdata->pclk))
- return PTR_ERR(drvdata->pclk);
-
if (res) {
drvdata->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(drvdata->base))
diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
index b044a4125310ba4f8c88df295ec3684ab266682f..02e0dc678a32c3b1f32fc955bf8871142e3412e1 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -217,6 +217,7 @@ static int funnel_probe(struct device *dev, struct resource *res)
struct coresight_platform_data *pdata = NULL;
struct funnel_drvdata *drvdata;
struct coresight_desc desc = { 0 };
+ int ret;
if (is_of_node(dev_fwnode(dev)) &&
of_device_is_compatible(dev->of_node, "arm,coresight-funnel"))
@@ -230,13 +231,9 @@ static int funnel_probe(struct device *dev, struct resource *res)
if (!drvdata)
return -ENOMEM;
- drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
- if (IS_ERR(drvdata->atclk))
- return PTR_ERR(drvdata->atclk);
-
- drvdata->pclk = coresight_get_enable_apb_pclk(dev);
- if (IS_ERR(drvdata->pclk))
- return PTR_ERR(drvdata->pclk);
+ ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk);
+ if (ret)
+ return ret;
/*
* Map the device base for dynamic-funnel, which has been
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
index 9e8bd36e7a9a2fd061f41c56242ac2b11549daf5..f1bbd12e63e0c130f945d8df34fb2334bd21336f 100644
--- a/drivers/hwtracing/coresight/coresight-replicator.c
+++ b/drivers/hwtracing/coresight/coresight-replicator.c
@@ -223,6 +223,7 @@ static int replicator_probe(struct device *dev, struct resource *res)
struct replicator_drvdata *drvdata;
struct coresight_desc desc = { 0 };
void __iomem *base;
+ int ret;
if (is_of_node(dev_fwnode(dev)) &&
of_device_is_compatible(dev->of_node, "arm,coresight-replicator"))
@@ -237,13 +238,9 @@ static int replicator_probe(struct device *dev, struct resource *res)
if (!drvdata)
return -ENOMEM;
- drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
- if (IS_ERR(drvdata->atclk))
- return PTR_ERR(drvdata->atclk);
-
- drvdata->pclk = coresight_get_enable_apb_pclk(dev);
- if (IS_ERR(drvdata->pclk))
- return PTR_ERR(drvdata->pclk);
+ ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk);
+ if (ret)
+ return ret;
/*
* Map the device base for dynamic-replicator, which has been
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index 57fbe3ad0fb20501d4e7e5c478d1e56e98685c40..a931282ec0eaf1b2a5db8ccc8f21789441cd634d 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -842,13 +842,10 @@ static int __stm_probe(struct device *dev, struct resource *res)
if (!drvdata)
return -ENOMEM;
- drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
- if (IS_ERR(drvdata->atclk))
- return PTR_ERR(drvdata->atclk);
+ ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk);
+ if (ret)
+ return ret;
- drvdata->pclk = coresight_get_enable_apb_pclk(dev);
- if (IS_ERR(drvdata->pclk))
- return PTR_ERR(drvdata->pclk);
dev_set_drvdata(dev, drvdata);
base = devm_ioremap_resource(dev, res);
diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index e867198b03e82892da7312c9dc1c69676602c598..e5ab4a0323354d826c831f68c71d81808cbcd8ff 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -785,13 +785,19 @@ static int __tmc_probe(struct device *dev, struct resource *res)
u32 devid;
void __iomem *base;
struct coresight_platform_data *pdata = NULL;
- struct tmc_drvdata *drvdata = dev_get_drvdata(dev);
+ struct tmc_drvdata *drvdata;
struct coresight_desc desc = { 0 };
struct coresight_dev_list *dev_list = NULL;
- drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
- if (IS_ERR(drvdata->atclk))
- return PTR_ERR(drvdata->atclk);
+ drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+ if (!drvdata)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev, drvdata);
+
+ ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk);
+ if (ret)
+ return ret;
ret = -ENOMEM;
@@ -898,14 +904,8 @@ static int __tmc_probe(struct device *dev, struct resource *res)
static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
{
- struct tmc_drvdata *drvdata;
int ret;
- drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL);
- if (!drvdata)
- return -ENOMEM;
-
- amba_set_drvdata(adev, drvdata);
ret = __tmc_probe(&adev->dev, &adev->res);
if (!ret)
pm_runtime_put(&adev->dev);
@@ -982,18 +982,8 @@ static struct amba_driver tmc_driver = {
static int tmc_platform_probe(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- struct tmc_drvdata *drvdata;
int ret = 0;
- drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
- if (!drvdata)
- return -ENOMEM;
-
- drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
- if (IS_ERR(drvdata->pclk))
- return PTR_ERR(drvdata->pclk);
-
- dev_set_drvdata(&pdev->dev, drvdata);
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
index 8d6179c83e5d3194d1f90e10c88fcc1faccf0cd7..5e47d761e1c4e99072eeb492c1eac7dd4285a591 100644
--- a/drivers/hwtracing/coresight/coresight-tpiu.c
+++ b/drivers/hwtracing/coresight/coresight-tpiu.c
@@ -132,6 +132,7 @@ static int __tpiu_probe(struct device *dev, struct resource *res)
struct coresight_platform_data *pdata = NULL;
struct tpiu_drvdata *drvdata;
struct coresight_desc desc = { 0 };
+ int ret;
desc.name = coresight_alloc_device_name(&tpiu_devs, dev);
if (!desc.name)
@@ -143,13 +144,10 @@ static int __tpiu_probe(struct device *dev, struct resource *res)
spin_lock_init(&drvdata->spinlock);
- drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
- if (IS_ERR(drvdata->atclk))
- return PTR_ERR(drvdata->atclk);
+ ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk);
+ if (ret)
+ return ret;
- drvdata->pclk = coresight_get_enable_apb_pclk(dev);
- if (IS_ERR(drvdata->pclk))
- return PTR_ERR(drvdata->pclk);
dev_set_drvdata(dev, drvdata);
/* Validity for the resource is already checked by the AMBA core */
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 9afa1f76c78a3347e54d94fe9a9ebed72e3fff8e..96cc814c1886f02bf802918b3ccb457b245bdbd6 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -474,27 +474,6 @@ static inline bool is_coresight_device(void __iomem *base)
return cid == CORESIGHT_CID;
}
-/*
- * Attempt to find and enable "APB clock" for the given device
- *
- * Returns:
- *
- * clk - Clock is found and enabled
- * NULL - Clock is not needed as it is managed by the AMBA bus driver
- * ERROR - Clock is found but failed to enable
- */
-static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev)
-{
- struct clk *pclk = NULL;
-
- if (!dev_is_amba(dev)) {
- pclk = devm_clk_get_enabled(dev, "apb_pclk");
- if (IS_ERR(pclk))
- pclk = devm_clk_get_enabled(dev, "apb");
- }
-
- return pclk;
-}
#define CORESIGHT_PIDRn(i) (0xFE0 + ((i) * 4))
@@ -726,4 +705,6 @@ void coresight_remove_driver(struct amba_driver *amba_drv,
struct platform_driver *pdev_drv);
int coresight_etm_get_trace_id(struct coresight_device *csdev, enum cs_mode mode,
struct coresight_device *sink);
+int coresight_get_enable_clocks(struct device *dev, struct clk **pclk,
+ struct clk **atclk);
#endif /* _LINUX_COREISGHT_H */
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 8/9] coresight: Make clock sequence consistent
2025-06-09 16:00 [PATCH v3 0/9] coresight: Fix and improve clock usage Leo Yan
` (6 preceding siblings ...)
2025-06-09 16:00 ` [PATCH v3 7/9] coresight: Consolidate clock enabling Leo Yan
@ 2025-06-09 16:00 ` Leo Yan
2025-06-09 16:00 ` [PATCH v3 9/9] coresight: Refactor runtime PM Leo Yan
8 siblings, 0 replies; 24+ messages in thread
From: Leo Yan @ 2025-06-09 16:00 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Anshuman Khandual,
Alexander Shishkin, Greg Kroah-Hartman
Cc: coresight, linux-arm-kernel, linux-kernel, Leo Yan
Since atclk is enabled after pclk during the probe phase, this commit
maintains the same sequence for the runtime resume flow.
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
Signed-off-by: Leo Yan <leo.yan@arm.com>
---
drivers/hwtracing/coresight/coresight-funnel.c | 6 +++---
drivers/hwtracing/coresight/coresight-replicator.c | 6 +++---
drivers/hwtracing/coresight/coresight-stm.c | 6 +++---
drivers/hwtracing/coresight/coresight-tpiu.c | 6 +++---
4 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
index 02e0dc678a32c3b1f32fc955bf8871142e3412e1..9dcfc5ce8845d9e01bb956dddab0d64de51ec397 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -297,11 +297,11 @@ static int funnel_runtime_resume(struct device *dev)
{
struct funnel_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_prepare_enable(drvdata->atclk);
-
if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
clk_prepare_enable(drvdata->pclk);
+
+ if (drvdata && !IS_ERR(drvdata->atclk))
+ clk_prepare_enable(drvdata->atclk);
return 0;
}
#endif
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
index f1bbd12e63e0c130f945d8df34fb2334bd21336f..e53095603b0c0419bc96a66b23d15bb54e75e634 100644
--- a/drivers/hwtracing/coresight/coresight-replicator.c
+++ b/drivers/hwtracing/coresight/coresight-replicator.c
@@ -335,11 +335,11 @@ static int replicator_runtime_resume(struct device *dev)
{
struct replicator_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_prepare_enable(drvdata->atclk);
-
if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
clk_prepare_enable(drvdata->pclk);
+
+ if (drvdata && !IS_ERR(drvdata->atclk))
+ clk_prepare_enable(drvdata->atclk);
return 0;
}
#endif
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index a931282ec0eaf1b2a5db8ccc8f21789441cd634d..ed68d8280b1945f38d1294a5b5f557a614c90c94 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -969,11 +969,11 @@ static int stm_runtime_resume(struct device *dev)
{
struct stm_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_prepare_enable(drvdata->atclk);
-
if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
clk_prepare_enable(drvdata->pclk);
+
+ if (drvdata && !IS_ERR(drvdata->atclk))
+ clk_prepare_enable(drvdata->atclk);
return 0;
}
#endif
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
index 5e47d761e1c4e99072eeb492c1eac7dd4285a591..1c5c2a82971490888c45508c68b516ab7dbf3eeb 100644
--- a/drivers/hwtracing/coresight/coresight-tpiu.c
+++ b/drivers/hwtracing/coresight/coresight-tpiu.c
@@ -218,11 +218,11 @@ static int tpiu_runtime_resume(struct device *dev)
{
struct tpiu_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_prepare_enable(drvdata->atclk);
-
if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
clk_prepare_enable(drvdata->pclk);
+
+ if (drvdata && !IS_ERR(drvdata->atclk))
+ clk_prepare_enable(drvdata->atclk);
return 0;
}
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 9/9] coresight: Refactor runtime PM
2025-06-09 16:00 [PATCH v3 0/9] coresight: Fix and improve clock usage Leo Yan
` (7 preceding siblings ...)
2025-06-09 16:00 ` [PATCH v3 8/9] coresight: Make clock sequence consistent Leo Yan
@ 2025-06-09 16:00 ` Leo Yan
2025-06-10 10:07 ` Anshuman Khandual
8 siblings, 1 reply; 24+ messages in thread
From: Leo Yan @ 2025-06-09 16:00 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Anshuman Khandual,
Alexander Shishkin, Greg Kroah-Hartman
Cc: coresight, linux-arm-kernel, linux-kernel, Leo Yan
The validation for driver data pointers and clock pointers are redundant
in the runtime PM callbacks. After a driver's probing, its driver data
and clocks have been initialized successfully, this ensures it is safe
to access driver data and clocks in the runtime PM callbacks. A corner
case is a clock pointer is NULL, in this case, the clock core layer can
handle it properly. So remove these redundant checking.
In runtime resume, respect values returned from clock function and add
error handling.
Signed-off-by: Leo Yan <leo.yan@arm.com>
---
drivers/hwtracing/coresight/coresight-cpu-debug.c | 8 +++-----
drivers/hwtracing/coresight/coresight-ctcu-core.c | 8 ++------
drivers/hwtracing/coresight/coresight-etb10.c | 8 ++------
drivers/hwtracing/coresight/coresight-etm3x-core.c | 8 ++------
drivers/hwtracing/coresight/coresight-funnel.c | 21 +++++++++++----------
drivers/hwtracing/coresight/coresight-replicator.c | 20 +++++++++++---------
drivers/hwtracing/coresight/coresight-stm.c | 20 +++++++++++---------
drivers/hwtracing/coresight/coresight-tpiu.c | 20 +++++++++++---------
8 files changed, 53 insertions(+), 60 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c
index 3edfb5d3d02056afcaab4da575d1101c68aeac80..5f21366406aae03edef9e4fb737e19941afb9ac2 100644
--- a/drivers/hwtracing/coresight/coresight-cpu-debug.c
+++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c
@@ -731,8 +731,8 @@ static int debug_runtime_suspend(struct device *dev)
{
struct debug_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_disable_unprepare(drvdata->pclk);
+ clk_disable_unprepare(drvdata->pclk);
+
return 0;
}
@@ -740,9 +740,7 @@ static int debug_runtime_resume(struct device *dev)
{
struct debug_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_prepare_enable(drvdata->pclk);
- return 0;
+ return clk_prepare_enable(drvdata->pclk);
}
#endif
diff --git a/drivers/hwtracing/coresight/coresight-ctcu-core.c b/drivers/hwtracing/coresight/coresight-ctcu-core.c
index 75b5114ef652e4a47c53fbd2b7811c1bab575645..c586495e9a088a63cec481a82fd9f4ec7c645160 100644
--- a/drivers/hwtracing/coresight/coresight-ctcu-core.c
+++ b/drivers/hwtracing/coresight/coresight-ctcu-core.c
@@ -278,8 +278,7 @@ static int ctcu_runtime_suspend(struct device *dev)
{
struct ctcu_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR_OR_NULL(drvdata->apb_clk))
- clk_disable_unprepare(drvdata->apb_clk);
+ clk_disable_unprepare(drvdata->apb_clk);
return 0;
}
@@ -288,10 +287,7 @@ static int ctcu_runtime_resume(struct device *dev)
{
struct ctcu_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR_OR_NULL(drvdata->apb_clk))
- clk_prepare_enable(drvdata->apb_clk);
-
- return 0;
+ return clk_prepare_enable(drvdata->apb_clk);
}
#endif
diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index 8e81b41eb22264f17606050fa8da277aae05c5cc..35db1b6093d154d67dc567df42f838e2ba3d1d58 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -809,8 +809,7 @@ static int etb_runtime_suspend(struct device *dev)
{
struct etb_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_disable_unprepare(drvdata->atclk);
+ clk_disable_unprepare(drvdata->atclk);
return 0;
}
@@ -819,10 +818,7 @@ static int etb_runtime_resume(struct device *dev)
{
struct etb_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_prepare_enable(drvdata->atclk);
-
- return 0;
+ return clk_prepare_enable(drvdata->atclk);
}
#endif
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c
index baba2245b1dfb31f4bf19080e20c33df3a5b854f..45630a1cd32fbd05ec8b2a6979f0174cacce365e 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c
@@ -925,8 +925,7 @@ static int etm_runtime_suspend(struct device *dev)
{
struct etm_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_disable_unprepare(drvdata->atclk);
+ clk_disable_unprepare(drvdata->atclk);
return 0;
}
@@ -935,10 +934,7 @@ static int etm_runtime_resume(struct device *dev)
{
struct etm_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_prepare_enable(drvdata->atclk);
-
- return 0;
+ return clk_prepare_enable(drvdata->atclk);
}
#endif
diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
index 9dcfc5ce8845d9e01bb956dddab0d64de51ec397..3b248e54471a38f501777fe162fea850d1c851b3 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -284,11 +284,8 @@ static int funnel_runtime_suspend(struct device *dev)
{
struct funnel_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_disable_unprepare(drvdata->atclk);
-
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_disable_unprepare(drvdata->pclk);
+ clk_disable_unprepare(drvdata->atclk);
+ clk_disable_unprepare(drvdata->pclk);
return 0;
}
@@ -296,13 +293,17 @@ static int funnel_runtime_suspend(struct device *dev)
static int funnel_runtime_resume(struct device *dev)
{
struct funnel_drvdata *drvdata = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(drvdata->pclk);
+ if (ret)
+ return ret;
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_prepare_enable(drvdata->pclk);
+ ret = clk_prepare_enable(drvdata->atclk);
+ if (ret)
+ clk_disable_unprepare(drvdata->pclk);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_prepare_enable(drvdata->atclk);
- return 0;
+ return ret;
}
#endif
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
index e53095603b0c0419bc96a66b23d15bb54e75e634..e6472658235dc479cec91ac18f3737f76f8c74f0 100644
--- a/drivers/hwtracing/coresight/coresight-replicator.c
+++ b/drivers/hwtracing/coresight/coresight-replicator.c
@@ -323,24 +323,26 @@ static int replicator_runtime_suspend(struct device *dev)
{
struct replicator_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_disable_unprepare(drvdata->atclk);
+ clk_disable_unprepare(drvdata->atclk);
+ clk_disable_unprepare(drvdata->pclk);
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- 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;
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_prepare_enable(drvdata->pclk);
+ ret = clk_prepare_enable(drvdata->pclk);
+ if (ret)
+ return ret;
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_prepare_enable(drvdata->atclk);
- return 0;
+ ret = clk_prepare_enable(drvdata->atclk);
+ if (ret)
+ clk_disable_unprepare(drvdata->pclk);
+
+ return ret;
}
#endif
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index ed68d8280b1945f38d1294a5b5f557a614c90c94..28230bbc9df2afec7b426e2fd4d4e4066f51e143 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -957,24 +957,26 @@ static int stm_runtime_suspend(struct device *dev)
{
struct stm_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_disable_unprepare(drvdata->atclk);
+ clk_disable_unprepare(drvdata->atclk);
+ clk_disable_unprepare(drvdata->pclk);
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_disable_unprepare(drvdata->pclk);
return 0;
}
static int stm_runtime_resume(struct device *dev)
{
struct stm_drvdata *drvdata = dev_get_drvdata(dev);
+ int ret;
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_prepare_enable(drvdata->pclk);
+ ret = clk_prepare_enable(drvdata->pclk);
+ if (ret)
+ return ret;
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_prepare_enable(drvdata->atclk);
- return 0;
+ ret = clk_prepare_enable(drvdata->atclk);
+ if (ret)
+ clk_disable_unprepare(drvdata->pclk);
+
+ return ret;
}
#endif
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
index 1c5c2a82971490888c45508c68b516ab7dbf3eeb..9463afdbda8ad74eee78c72185fe7603f81b7888 100644
--- a/drivers/hwtracing/coresight/coresight-tpiu.c
+++ b/drivers/hwtracing/coresight/coresight-tpiu.c
@@ -206,24 +206,26 @@ static int tpiu_runtime_suspend(struct device *dev)
{
struct tpiu_drvdata *drvdata = dev_get_drvdata(dev);
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_disable_unprepare(drvdata->atclk);
+ clk_disable_unprepare(drvdata->atclk);
+ clk_disable_unprepare(drvdata->pclk);
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_disable_unprepare(drvdata->pclk);
return 0;
}
static int tpiu_runtime_resume(struct device *dev)
{
struct tpiu_drvdata *drvdata = dev_get_drvdata(dev);
+ int ret;
- if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
- clk_prepare_enable(drvdata->pclk);
+ ret = clk_prepare_enable(drvdata->pclk);
+ if (ret)
+ return ret;
- if (drvdata && !IS_ERR(drvdata->atclk))
- clk_prepare_enable(drvdata->atclk);
- return 0;
+ ret = clk_prepare_enable(drvdata->atclk);
+ if (ret)
+ clk_disable_unprepare(drvdata->pclk);
+
+ return ret;
}
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v3 4/9] coresight: Appropriately disable programming clocks
2025-06-09 16:00 ` [PATCH v3 4/9] coresight: Appropriately disable programming clocks Leo Yan
@ 2025-06-09 16:11 ` Suzuki K Poulose
2025-06-09 16:38 ` Leo Yan
2025-06-24 4:37 ` Anshuman Khandual
1 sibling, 1 reply; 24+ messages in thread
From: Suzuki K Poulose @ 2025-06-09 16:11 UTC (permalink / raw)
To: Leo Yan, Mike Leach, James Clark, Anshuman Khandual,
Alexander Shishkin, Greg Kroah-Hartman
Cc: coresight, linux-arm-kernel, linux-kernel
On 09/06/2025 17:00, Leo Yan wrote:
> Some CoreSight components have programming clocks (pclk) and are enabled
> using clk_get() and clk_prepare_enable(). However, in many cases, these
> clocks are not disabled when modules exit and only released by clk_put().
>
> To fix the issue, this commit refactors coresight_get_enable_apb_pclk()
> by replacing clk_get() and clk_prepare_enable() with
> devm_clk_get_enabled() for enabling APB clock. Callers are updated
> to reuse the returned error value.
>
> With the change, programming clocks are managed as resources in driver
> model layer, allowing clock cleanup to be handled automatically. As a
> result, manual cleanup operations are no longer needed and are removed
> from the Coresight drivers.
>
> Fixes: 73d779a03a76 ("coresight: etm4x: Change etm4_platform_driver driver for MMIO devices")
This looks suspicious. This patch covers a lot of components, but the
above commit is only affecting ETMv4 ?
The patch as such looks good to me.
Suzuki
> Signed-off-by: Leo Yan <leo.yan@arm.com>
> ---
> drivers/hwtracing/coresight/coresight-catu.c | 9 ++-------
> drivers/hwtracing/coresight/coresight-cpu-debug.c | 6 +-----
> drivers/hwtracing/coresight/coresight-ctcu-core.c | 10 ++--------
> drivers/hwtracing/coresight/coresight-etm4x-core.c | 9 ++-------
> drivers/hwtracing/coresight/coresight-funnel.c | 6 +-----
> drivers/hwtracing/coresight/coresight-replicator.c | 6 +-----
> drivers/hwtracing/coresight/coresight-stm.c | 4 +---
> drivers/hwtracing/coresight/coresight-tmc-core.c | 4 +---
> drivers/hwtracing/coresight/coresight-tpiu.c | 4 +---
> include/linux/coresight.h | 16 +++-------------
> 10 files changed, 15 insertions(+), 59 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c
> index af2a55f0c907c392d092a50612b23c115a1b0f5f..4c345ff2cff141ea63c2220393e5fdd00c449ca6 100644
> --- a/drivers/hwtracing/coresight/coresight-catu.c
> +++ b/drivers/hwtracing/coresight/coresight-catu.c
> @@ -636,7 +636,7 @@ static int catu_platform_probe(struct platform_device *pdev)
>
> drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
> if (IS_ERR(drvdata->pclk))
> - return -ENODEV;
> + return PTR_ERR(drvdata->pclk);
>
> pm_runtime_get_noresume(&pdev->dev);
> pm_runtime_set_active(&pdev->dev);
> @@ -645,11 +645,8 @@ static int catu_platform_probe(struct platform_device *pdev)
> dev_set_drvdata(&pdev->dev, drvdata);
> ret = __catu_probe(&pdev->dev, res);
> pm_runtime_put(&pdev->dev);
> - if (ret) {
> + if (ret)
> pm_runtime_disable(&pdev->dev);
> - if (!IS_ERR_OR_NULL(drvdata->pclk))
> - clk_put(drvdata->pclk);
> - }
>
> return ret;
> }
> @@ -663,8 +660,6 @@ static void catu_platform_remove(struct platform_device *pdev)
>
> __catu_remove(&pdev->dev);
> pm_runtime_disable(&pdev->dev);
> - if (!IS_ERR_OR_NULL(drvdata->pclk))
> - clk_put(drvdata->pclk);
> }
>
> #ifdef CONFIG_PM
> diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c
> index a871d997330b09bdb741f35c59108b0b3252cc54..e39dfb886688e111eee95d4294f37fa85baccd14 100644
> --- a/drivers/hwtracing/coresight/coresight-cpu-debug.c
> +++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c
> @@ -699,7 +699,7 @@ static int debug_platform_probe(struct platform_device *pdev)
>
> drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
> if (IS_ERR(drvdata->pclk))
> - return -ENODEV;
> + return PTR_ERR(drvdata->pclk);
>
> dev_set_drvdata(&pdev->dev, drvdata);
> pm_runtime_get_noresume(&pdev->dev);
> @@ -710,8 +710,6 @@ static int debug_platform_probe(struct platform_device *pdev)
> if (ret) {
> pm_runtime_put_noidle(&pdev->dev);
> pm_runtime_disable(&pdev->dev);
> - if (!IS_ERR_OR_NULL(drvdata->pclk))
> - clk_put(drvdata->pclk);
> }
> return ret;
> }
> @@ -725,8 +723,6 @@ static void debug_platform_remove(struct platform_device *pdev)
>
> __debug_remove(&pdev->dev);
> pm_runtime_disable(&pdev->dev);
> - if (!IS_ERR_OR_NULL(drvdata->pclk))
> - clk_put(drvdata->pclk);
> }
>
> #ifdef CONFIG_ACPI
> diff --git a/drivers/hwtracing/coresight/coresight-ctcu-core.c b/drivers/hwtracing/coresight/coresight-ctcu-core.c
> index c6bafc96db963310b5e77a095953c83a172cfc7c..de279efe340581ceabfb9e1cd1e7fe4b5e4f826e 100644
> --- a/drivers/hwtracing/coresight/coresight-ctcu-core.c
> +++ b/drivers/hwtracing/coresight/coresight-ctcu-core.c
> @@ -209,7 +209,7 @@ static int ctcu_probe(struct platform_device *pdev)
>
> drvdata->apb_clk = coresight_get_enable_apb_pclk(dev);
> if (IS_ERR(drvdata->apb_clk))
> - return -ENODEV;
> + return PTR_ERR(drvdata->apb_clk);
>
> cfgs = of_device_get_match_data(dev);
> if (cfgs) {
> @@ -233,12 +233,8 @@ static int ctcu_probe(struct platform_device *pdev)
> desc.access = CSDEV_ACCESS_IOMEM(base);
>
> drvdata->csdev = coresight_register(&desc);
> - if (IS_ERR(drvdata->csdev)) {
> - if (!IS_ERR_OR_NULL(drvdata->apb_clk))
> - clk_put(drvdata->apb_clk);
> -
> + if (IS_ERR(drvdata->csdev))
> return PTR_ERR(drvdata->csdev);
> - }
>
> return 0;
> }
> @@ -275,8 +271,6 @@ static void ctcu_platform_remove(struct platform_device *pdev)
>
> ctcu_remove(pdev);
> pm_runtime_disable(&pdev->dev);
> - if (!IS_ERR_OR_NULL(drvdata->apb_clk))
> - clk_put(drvdata->apb_clk);
> }
>
> #ifdef CONFIG_PM
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> index 205121c14d72ec2f6a193dccb94b7cfd5c314e26..1915da95b93d953a61778a71b4880c87b91fe17a 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -2303,14 +2303,12 @@ static int etm4_probe_platform_dev(struct platform_device *pdev)
>
> drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
> if (IS_ERR(drvdata->pclk))
> - return -ENODEV;
> + return PTR_ERR(drvdata->pclk);
>
> if (res) {
> drvdata->base = devm_ioremap_resource(&pdev->dev, res);
> - if (IS_ERR(drvdata->base)) {
> - clk_put(drvdata->pclk);
> + if (IS_ERR(drvdata->base))
> return PTR_ERR(drvdata->base);
> - }
> }
>
> dev_set_drvdata(&pdev->dev, drvdata);
> @@ -2417,9 +2415,6 @@ static void etm4_remove_platform_dev(struct platform_device *pdev)
> if (drvdata)
> etm4_remove_dev(drvdata);
> pm_runtime_disable(&pdev->dev);
> -
> - if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
> - clk_put(drvdata->pclk);
> }
>
> static const struct amba_id etm4_ids[] = {
> diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
> index b1922dbe9292b02c91ca5730998e59ecdb08fdc7..36fc4e991458c112521c4261d73f3e58e9a3f995 100644
> --- a/drivers/hwtracing/coresight/coresight-funnel.c
> +++ b/drivers/hwtracing/coresight/coresight-funnel.c
> @@ -240,7 +240,7 @@ static int funnel_probe(struct device *dev, struct resource *res)
>
> drvdata->pclk = coresight_get_enable_apb_pclk(dev);
> if (IS_ERR(drvdata->pclk))
> - return -ENODEV;
> + return PTR_ERR(drvdata->pclk);
>
> /*
> * Map the device base for dynamic-funnel, which has been
> @@ -284,8 +284,6 @@ static int funnel_probe(struct device *dev, struct resource *res)
> out_disable_clk:
> if (ret && !IS_ERR_OR_NULL(drvdata->atclk))
> clk_disable_unprepare(drvdata->atclk);
> - if (ret && !IS_ERR_OR_NULL(drvdata->pclk))
> - clk_disable_unprepare(drvdata->pclk);
> return ret;
> }
>
> @@ -355,8 +353,6 @@ static void funnel_platform_remove(struct platform_device *pdev)
>
> funnel_remove(&pdev->dev);
> pm_runtime_disable(&pdev->dev);
> - if (!IS_ERR_OR_NULL(drvdata->pclk))
> - clk_put(drvdata->pclk);
> }
>
> static const struct of_device_id funnel_match[] = {
> diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
> index 06efd2b01a0f71620eac71166567d14655b58403..6dd24eb10a94b0eb28f4f27afab845227e22b96c 100644
> --- a/drivers/hwtracing/coresight/coresight-replicator.c
> +++ b/drivers/hwtracing/coresight/coresight-replicator.c
> @@ -247,7 +247,7 @@ static int replicator_probe(struct device *dev, struct resource *res)
>
> drvdata->pclk = coresight_get_enable_apb_pclk(dev);
> if (IS_ERR(drvdata->pclk))
> - return -ENODEV;
> + return PTR_ERR(drvdata->pclk);
>
> /*
> * Map the device base for dynamic-replicator, which has been
> @@ -296,8 +296,6 @@ static int replicator_probe(struct device *dev, struct resource *res)
> out_disable_clk:
> if (ret && !IS_ERR_OR_NULL(drvdata->atclk))
> clk_disable_unprepare(drvdata->atclk);
> - if (ret && !IS_ERR_OR_NULL(drvdata->pclk))
> - clk_disable_unprepare(drvdata->pclk);
> return ret;
> }
>
> @@ -335,8 +333,6 @@ static void replicator_platform_remove(struct platform_device *pdev)
>
> replicator_remove(&pdev->dev);
> pm_runtime_disable(&pdev->dev);
> - if (!IS_ERR_OR_NULL(drvdata->pclk))
> - clk_put(drvdata->pclk);
> }
>
> #ifdef CONFIG_PM
> diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
> index e45c6c7204b4491e0f879bc7d5d445aa1d3118be..88ee453b2815444a550a2b932b28367eb93336b8 100644
> --- a/drivers/hwtracing/coresight/coresight-stm.c
> +++ b/drivers/hwtracing/coresight/coresight-stm.c
> @@ -851,7 +851,7 @@ static int __stm_probe(struct device *dev, struct resource *res)
>
> drvdata->pclk = coresight_get_enable_apb_pclk(dev);
> if (IS_ERR(drvdata->pclk))
> - return -ENODEV;
> + return PTR_ERR(drvdata->pclk);
> dev_set_drvdata(dev, drvdata);
>
> base = devm_ioremap_resource(dev, res);
> @@ -1033,8 +1033,6 @@ static void stm_platform_remove(struct platform_device *pdev)
>
> __stm_remove(&pdev->dev);
> pm_runtime_disable(&pdev->dev);
> - if (!IS_ERR_OR_NULL(drvdata->pclk))
> - clk_put(drvdata->pclk);
> }
>
> #ifdef CONFIG_ACPI
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
> index 0b5e7635a084d226619e69189a2ecbaff754ec43..e867198b03e82892da7312c9dc1c69676602c598 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
> @@ -991,7 +991,7 @@ static int tmc_platform_probe(struct platform_device *pdev)
>
> drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
> if (IS_ERR(drvdata->pclk))
> - return -ENODEV;
> + return PTR_ERR(drvdata->pclk);
>
> dev_set_drvdata(&pdev->dev, drvdata);
> pm_runtime_get_noresume(&pdev->dev);
> @@ -1015,8 +1015,6 @@ static void tmc_platform_remove(struct platform_device *pdev)
>
> __tmc_remove(&pdev->dev);
> pm_runtime_disable(&pdev->dev);
> - if (!IS_ERR_OR_NULL(drvdata->pclk))
> - clk_put(drvdata->pclk);
> }
>
> #ifdef CONFIG_PM
> diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
> index 3e01592884280819c16398cbb5e09cbaee5d3efb..b2559c6fac6d2f02e0038e583cd324d7165c5aee 100644
> --- a/drivers/hwtracing/coresight/coresight-tpiu.c
> +++ b/drivers/hwtracing/coresight/coresight-tpiu.c
> @@ -153,7 +153,7 @@ static int __tpiu_probe(struct device *dev, struct resource *res)
>
> drvdata->pclk = coresight_get_enable_apb_pclk(dev);
> if (IS_ERR(drvdata->pclk))
> - return -ENODEV;
> + return PTR_ERR(drvdata->pclk);
> dev_set_drvdata(dev, drvdata);
>
> /* Validity for the resource is already checked by the AMBA core */
> @@ -293,8 +293,6 @@ static void tpiu_platform_remove(struct platform_device *pdev)
>
> __tpiu_remove(&pdev->dev);
> pm_runtime_disable(&pdev->dev);
> - if (!IS_ERR_OR_NULL(drvdata->pclk))
> - clk_put(drvdata->pclk);
> }
>
> #ifdef CONFIG_ACPI
> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> index 4ac65c68bbf44b98db22c3dad2d83a224ce5278e..dd2b4cc7a2b70cf060a3207548fe80e3824c489f 100644
> --- a/include/linux/coresight.h
> +++ b/include/linux/coresight.h
> @@ -480,26 +480,16 @@ static inline bool is_coresight_device(void __iomem *base)
> * Returns:
> *
> * clk - Clock is found and enabled
> - * NULL - clock is not found
> * ERROR - Clock is found but failed to enable
> */
> static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev)
> {
> struct clk *pclk;
> - int ret;
>
> - pclk = clk_get(dev, "apb_pclk");
> - if (IS_ERR(pclk)) {
> - pclk = clk_get(dev, "apb");
> - if (IS_ERR(pclk))
> - return NULL;
> - }
> + pclk = devm_clk_get_enabled(dev, "apb_pclk");
> + if (IS_ERR(pclk))
> + pclk = devm_clk_get_enabled(dev, "apb");
>
> - ret = clk_prepare_enable(pclk);
> - if (ret) {
> - clk_put(pclk);
> - return ERR_PTR(ret);
> - }
> return pclk;
> }
>
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 4/9] coresight: Appropriately disable programming clocks
2025-06-09 16:11 ` Suzuki K Poulose
@ 2025-06-09 16:38 ` Leo Yan
2025-06-24 4:23 ` Anshuman Khandual
0 siblings, 1 reply; 24+ messages in thread
From: Leo Yan @ 2025-06-09 16:38 UTC (permalink / raw)
To: Suzuki K Poulose
Cc: Mike Leach, James Clark, Anshuman Khandual, Alexander Shishkin,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel
On Mon, Jun 09, 2025 at 05:11:21PM +0100, Suzuki Kuruppassery Poulose wrote:
> On 09/06/2025 17:00, Leo Yan wrote:
> > Some CoreSight components have programming clocks (pclk) and are enabled
> > using clk_get() and clk_prepare_enable(). However, in many cases, these
> > clocks are not disabled when modules exit and only released by clk_put().
> >
> > To fix the issue, this commit refactors coresight_get_enable_apb_pclk()
> > by replacing clk_get() and clk_prepare_enable() with
> > devm_clk_get_enabled() for enabling APB clock. Callers are updated
> > to reuse the returned error value.
> >
> > With the change, programming clocks are managed as resources in driver
> > model layer, allowing clock cleanup to be handled automatically. As a
> > result, manual cleanup operations are no longer needed and are removed
> > from the Coresight drivers.
> >
> > Fixes: 73d779a03a76 ("coresight: etm4x: Change etm4_platform_driver driver for MMIO devices")
>
> This looks suspicious. This patch covers a lot of components, but the
> above commit is only affecting ETMv4 ?
Since commit 73d779a03a76 is the earliest patch that introduced the
issue, it has been selected as the fix tag. We assume this will cover
any subsequent changes that have the same issue.
> The patch as such looks good to me.
Thanks for review!
> Suzuki
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 5/9] coresight: Appropriately disable trace bus clocks
[not found] ` <89f9fede-3a0f-4ed6-a42d-43827f7a4fca@arm.com>
@ 2025-06-09 16:43 ` Leo Yan
0 siblings, 0 replies; 24+ messages in thread
From: Leo Yan @ 2025-06-09 16:43 UTC (permalink / raw)
To: Suzuki K Poulose
Cc: Mike Leach, James Clark, Anshuman Khandual, Alexander Shishkin,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel
On Mon, Jun 09, 2025 at 05:14:09PM +0100, Suzuki Kuruppassery Poulose wrote:
> On 09/06/2025 17:00, Leo Yan wrote:
> > Some CoreSight components have trace bus clocks 'atclk' and are enabled
> > using clk_prepare_enable(). These clocks are not disabled when modules
> > exit.
> >
> > As atclk is optional, use devm_clk_get_optional_enabled() to manage it.
> > The benefit is the driver model layer can automatically disable and
> > release clocks.
> >
> > Check the returned value with IS_ERR() to detect errors but leave the
> > NULL pointer case if the clock is not found. And remove the error
> > handling codes which are no longer needed.
> >
> > Fixes: d1839e687773 ("coresight: etm: retrieve and handle atclk")
> > Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
> > Signed-off-by: Leo Yan <leo.yan@arm.com>
>
> Can we consolidate the ATCLK handling to the core coresight helper for
> APB clocks ? It is an optional clock for all devices anyways ?
Yes. ATCLK is always optional.
Could you check the patch 07? It is exactly a consolidation to put ATCLK
and APB clocks into a central place.
Thanks,
Leo
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 6/9] coresight: Avoid enable programming clock duplicately
2025-06-09 16:00 ` [PATCH v3 6/9] coresight: Avoid enable programming clock duplicately Leo Yan
@ 2025-06-09 16:58 ` Suzuki K Poulose
2025-06-09 17:14 ` Leo Yan
2025-06-24 5:11 ` Anshuman Khandual
1 sibling, 1 reply; 24+ messages in thread
From: Suzuki K Poulose @ 2025-06-09 16:58 UTC (permalink / raw)
To: Leo Yan, Mike Leach, James Clark, Anshuman Khandual,
Alexander Shishkin, Greg Kroah-Hartman
Cc: coresight, linux-arm-kernel, linux-kernel
On 09/06/2025 17:00, Leo Yan wrote:
> The programming clock is enabled by AMBA bus driver before a dynamic
> probe. As a result, a CoreSight driver may redundantly enable the same
> clock.
>
> To avoid this, add a check for device type and skip enabling the
> programming clock for AMBA devices. The returned NULL pointer will be
> tolerated by the drivers.
>
> Fixes: 73d779a03a76 ("coresight: etm4x: Change etm4_platform_driver driver for MMIO devices")
> Signed-off-by: Leo Yan <leo.yan@arm.com>
> ---
> include/linux/coresight.h | 11 +++++++----
> 1 file changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> index dd2b4cc7a2b70cf060a3207548fe80e3824c489f..9afa1f76c78a3347e54d94fe9a9ebed72e3fff8e 100644
> --- a/include/linux/coresight.h
> +++ b/include/linux/coresight.h
> @@ -480,15 +480,18 @@ static inline bool is_coresight_device(void __iomem *base)
> * Returns:
> *
> * clk - Clock is found and enabled
> + * NULL - Clock is not needed as it is managed by the AMBA bus driver
> * ERROR - Clock is found but failed to enable
> */
> static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev)
> {
> - struct clk *pclk;
> + struct clk *pclk = NULL;
>
> - pclk = devm_clk_get_enabled(dev, "apb_pclk");
> - if (IS_ERR(pclk))
> - pclk = devm_clk_get_enabled(dev, "apb");
> + if (!dev_is_amba(dev)) {
> + pclk = devm_clk_get_enabled(dev, "apb_pclk");
> + if (IS_ERR(pclk))
> + pclk = devm_clk_get_enabled(dev, "apb");
AMBA driver doesn't handle "apb" clock ? So we may need to retain that
here ?
Otherwise looks good to me.
Suzuki
> + }
>
> return pclk;
> }
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 6/9] coresight: Avoid enable programming clock duplicately
2025-06-09 16:58 ` Suzuki K Poulose
@ 2025-06-09 17:14 ` Leo Yan
2025-06-10 10:39 ` Anshuman Khandual
0 siblings, 1 reply; 24+ messages in thread
From: Leo Yan @ 2025-06-09 17:14 UTC (permalink / raw)
To: Suzuki K Poulose
Cc: Mike Leach, James Clark, Anshuman Khandual, Alexander Shishkin,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel
On Mon, Jun 09, 2025 at 05:58:34PM +0100, Suzuki Kuruppassery Poulose wrote:
[...]
> > static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev)
> > {
> > - struct clk *pclk;
> > + struct clk *pclk = NULL;
> > - pclk = devm_clk_get_enabled(dev, "apb_pclk");
> > - if (IS_ERR(pclk))
> > - pclk = devm_clk_get_enabled(dev, "apb");
> > + if (!dev_is_amba(dev)) {
> > + pclk = devm_clk_get_enabled(dev, "apb_pclk");
> > + if (IS_ERR(pclk))
> > + pclk = devm_clk_get_enabled(dev, "apb");
>
> AMBA driver doesn't handle "apb" clock ? So we may need to retain that here
> ?
Here checks the condition "if (!dev_is_amba(dev))", it means the device
is not an AMBA device (e.g., a platform device), the APB clock is
enabled at here.
Otherwise, for a AMBA device, the AMBA bus layer will help to enable
APB clock.
> Otherwise looks good to me.
>
> Suzuki
> > + }
> > return pclk;
> > }
> >
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 9/9] coresight: Refactor runtime PM
2025-06-09 16:00 ` [PATCH v3 9/9] coresight: Refactor runtime PM Leo Yan
@ 2025-06-10 10:07 ` Anshuman Khandual
0 siblings, 0 replies; 24+ messages in thread
From: Anshuman Khandual @ 2025-06-10 10:07 UTC (permalink / raw)
To: Leo Yan, Suzuki K Poulose, Mike Leach, James Clark,
Alexander Shishkin, Greg Kroah-Hartman
Cc: coresight, linux-arm-kernel, linux-kernel
On 09/06/25 9:30 PM, Leo Yan wrote:
> The validation for driver data pointers and clock pointers are redundant
> in the runtime PM callbacks. After a driver's probing, its driver data
> and clocks have been initialized successfully, this ensures it is safe
> to access driver data and clocks in the runtime PM callbacks. A corner
> case is a clock pointer is NULL, in this case, the clock core layer can
> handle it properly. So remove these redundant checking.
>
> In runtime resume, respect values returned from clock function and add
> error handling.
Makes sense.
>
> Signed-off-by: Leo Yan <leo.yan@arm.com>
This looks like a good clean up and streamlining.
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
> drivers/hwtracing/coresight/coresight-cpu-debug.c | 8 +++-----
> drivers/hwtracing/coresight/coresight-ctcu-core.c | 8 ++------
> drivers/hwtracing/coresight/coresight-etb10.c | 8 ++------
> drivers/hwtracing/coresight/coresight-etm3x-core.c | 8 ++------
> drivers/hwtracing/coresight/coresight-funnel.c | 21 +++++++++++----------
> drivers/hwtracing/coresight/coresight-replicator.c | 20 +++++++++++---------
> drivers/hwtracing/coresight/coresight-stm.c | 20 +++++++++++---------
> drivers/hwtracing/coresight/coresight-tpiu.c | 20 +++++++++++---------
> 8 files changed, 53 insertions(+), 60 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c
> index 3edfb5d3d02056afcaab4da575d1101c68aeac80..5f21366406aae03edef9e4fb737e19941afb9ac2 100644
> --- a/drivers/hwtracing/coresight/coresight-cpu-debug.c
> +++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c
> @@ -731,8 +731,8 @@ static int debug_runtime_suspend(struct device *dev)
> {
> struct debug_drvdata *drvdata = dev_get_drvdata(dev);
>
> - if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
> - clk_disable_unprepare(drvdata->pclk);
> + clk_disable_unprepare(drvdata->pclk);
> +
> return 0;
> }
>
> @@ -740,9 +740,7 @@ static int debug_runtime_resume(struct device *dev)
> {
> struct debug_drvdata *drvdata = dev_get_drvdata(dev);
>
> - if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
> - clk_prepare_enable(drvdata->pclk);
> - return 0;
> + return clk_prepare_enable(drvdata->pclk);
> }
> #endif
>
> diff --git a/drivers/hwtracing/coresight/coresight-ctcu-core.c b/drivers/hwtracing/coresight/coresight-ctcu-core.c
> index 75b5114ef652e4a47c53fbd2b7811c1bab575645..c586495e9a088a63cec481a82fd9f4ec7c645160 100644
> --- a/drivers/hwtracing/coresight/coresight-ctcu-core.c
> +++ b/drivers/hwtracing/coresight/coresight-ctcu-core.c
> @@ -278,8 +278,7 @@ static int ctcu_runtime_suspend(struct device *dev)
> {
> struct ctcu_drvdata *drvdata = dev_get_drvdata(dev);
>
> - if (drvdata && !IS_ERR_OR_NULL(drvdata->apb_clk))
> - clk_disable_unprepare(drvdata->apb_clk);
> + clk_disable_unprepare(drvdata->apb_clk);
>
> return 0;
> }
> @@ -288,10 +287,7 @@ static int ctcu_runtime_resume(struct device *dev)
> {
> struct ctcu_drvdata *drvdata = dev_get_drvdata(dev);
>
> - if (drvdata && !IS_ERR_OR_NULL(drvdata->apb_clk))
> - clk_prepare_enable(drvdata->apb_clk);
> -
> - return 0;
> + return clk_prepare_enable(drvdata->apb_clk);
> }
> #endif
>
> diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
> index 8e81b41eb22264f17606050fa8da277aae05c5cc..35db1b6093d154d67dc567df42f838e2ba3d1d58 100644
> --- a/drivers/hwtracing/coresight/coresight-etb10.c
> +++ b/drivers/hwtracing/coresight/coresight-etb10.c
> @@ -809,8 +809,7 @@ static int etb_runtime_suspend(struct device *dev)
> {
> struct etb_drvdata *drvdata = dev_get_drvdata(dev);
>
> - if (drvdata && !IS_ERR(drvdata->atclk))
> - clk_disable_unprepare(drvdata->atclk);
> + clk_disable_unprepare(drvdata->atclk);
>
> return 0;
> }
> @@ -819,10 +818,7 @@ static int etb_runtime_resume(struct device *dev)
> {
> struct etb_drvdata *drvdata = dev_get_drvdata(dev);
>
> - if (drvdata && !IS_ERR(drvdata->atclk))
> - clk_prepare_enable(drvdata->atclk);
> -
> - return 0;
> + return clk_prepare_enable(drvdata->atclk);
> }
> #endif
>
> diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c
> index baba2245b1dfb31f4bf19080e20c33df3a5b854f..45630a1cd32fbd05ec8b2a6979f0174cacce365e 100644
> --- a/drivers/hwtracing/coresight/coresight-etm3x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c
> @@ -925,8 +925,7 @@ static int etm_runtime_suspend(struct device *dev)
> {
> struct etm_drvdata *drvdata = dev_get_drvdata(dev);
>
> - if (drvdata && !IS_ERR(drvdata->atclk))
> - clk_disable_unprepare(drvdata->atclk);
> + clk_disable_unprepare(drvdata->atclk);
>
> return 0;
> }
> @@ -935,10 +934,7 @@ static int etm_runtime_resume(struct device *dev)
> {
> struct etm_drvdata *drvdata = dev_get_drvdata(dev);
>
> - if (drvdata && !IS_ERR(drvdata->atclk))
> - clk_prepare_enable(drvdata->atclk);
> -
> - return 0;
> + return clk_prepare_enable(drvdata->atclk);
> }
> #endif
>
> diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
> index 9dcfc5ce8845d9e01bb956dddab0d64de51ec397..3b248e54471a38f501777fe162fea850d1c851b3 100644
> --- a/drivers/hwtracing/coresight/coresight-funnel.c
> +++ b/drivers/hwtracing/coresight/coresight-funnel.c
> @@ -284,11 +284,8 @@ static int funnel_runtime_suspend(struct device *dev)
> {
> struct funnel_drvdata *drvdata = dev_get_drvdata(dev);
>
> - if (drvdata && !IS_ERR(drvdata->atclk))
> - clk_disable_unprepare(drvdata->atclk);
> -
> - if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
> - clk_disable_unprepare(drvdata->pclk);
> + clk_disable_unprepare(drvdata->atclk);
> + clk_disable_unprepare(drvdata->pclk);
>
> return 0;
> }
> @@ -296,13 +293,17 @@ static int funnel_runtime_suspend(struct device *dev)
> static int funnel_runtime_resume(struct device *dev)
> {
> struct funnel_drvdata *drvdata = dev_get_drvdata(dev);
> + int ret;
> +
> + ret = clk_prepare_enable(drvdata->pclk);
> + if (ret)
> + return ret;
>
> - if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
> - clk_prepare_enable(drvdata->pclk);
> + ret = clk_prepare_enable(drvdata->atclk);
> + if (ret)
> + clk_disable_unprepare(drvdata->pclk);
>
> - if (drvdata && !IS_ERR(drvdata->atclk))
> - clk_prepare_enable(drvdata->atclk);
> - return 0;
> + return ret;
> }
> #endif
>
> diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
> index e53095603b0c0419bc96a66b23d15bb54e75e634..e6472658235dc479cec91ac18f3737f76f8c74f0 100644
> --- a/drivers/hwtracing/coresight/coresight-replicator.c
> +++ b/drivers/hwtracing/coresight/coresight-replicator.c
> @@ -323,24 +323,26 @@ static int replicator_runtime_suspend(struct device *dev)
> {
> struct replicator_drvdata *drvdata = dev_get_drvdata(dev);
>
> - if (drvdata && !IS_ERR(drvdata->atclk))
> - clk_disable_unprepare(drvdata->atclk);
> + clk_disable_unprepare(drvdata->atclk);
> + clk_disable_unprepare(drvdata->pclk);
>
> - if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
> - 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;
>
> - if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
> - clk_prepare_enable(drvdata->pclk);
> + ret = clk_prepare_enable(drvdata->pclk);
> + if (ret)
> + return ret;
>
> - if (drvdata && !IS_ERR(drvdata->atclk))
> - clk_prepare_enable(drvdata->atclk);
> - return 0;
> + ret = clk_prepare_enable(drvdata->atclk);
> + if (ret)
> + clk_disable_unprepare(drvdata->pclk);
> +
> + return ret;
> }
> #endif
>
> diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
> index ed68d8280b1945f38d1294a5b5f557a614c90c94..28230bbc9df2afec7b426e2fd4d4e4066f51e143 100644
> --- a/drivers/hwtracing/coresight/coresight-stm.c
> +++ b/drivers/hwtracing/coresight/coresight-stm.c
> @@ -957,24 +957,26 @@ static int stm_runtime_suspend(struct device *dev)
> {
> struct stm_drvdata *drvdata = dev_get_drvdata(dev);
>
> - if (drvdata && !IS_ERR(drvdata->atclk))
> - clk_disable_unprepare(drvdata->atclk);
> + clk_disable_unprepare(drvdata->atclk);
> + clk_disable_unprepare(drvdata->pclk);
>
> - if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
> - clk_disable_unprepare(drvdata->pclk);
> return 0;
> }
>
> static int stm_runtime_resume(struct device *dev)
> {
> struct stm_drvdata *drvdata = dev_get_drvdata(dev);
> + int ret;
>
> - if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
> - clk_prepare_enable(drvdata->pclk);
> + ret = clk_prepare_enable(drvdata->pclk);
> + if (ret)
> + return ret;
>
> - if (drvdata && !IS_ERR(drvdata->atclk))
> - clk_prepare_enable(drvdata->atclk);
> - return 0;
> + ret = clk_prepare_enable(drvdata->atclk);
> + if (ret)
> + clk_disable_unprepare(drvdata->pclk);
> +
> + return ret;
> }
> #endif
>
> diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
> index 1c5c2a82971490888c45508c68b516ab7dbf3eeb..9463afdbda8ad74eee78c72185fe7603f81b7888 100644
> --- a/drivers/hwtracing/coresight/coresight-tpiu.c
> +++ b/drivers/hwtracing/coresight/coresight-tpiu.c
> @@ -206,24 +206,26 @@ static int tpiu_runtime_suspend(struct device *dev)
> {
> struct tpiu_drvdata *drvdata = dev_get_drvdata(dev);
>
> - if (drvdata && !IS_ERR(drvdata->atclk))
> - clk_disable_unprepare(drvdata->atclk);
> + clk_disable_unprepare(drvdata->atclk);
> + clk_disable_unprepare(drvdata->pclk);
>
> - if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
> - clk_disable_unprepare(drvdata->pclk);
> return 0;
> }
>
> static int tpiu_runtime_resume(struct device *dev)
> {
> struct tpiu_drvdata *drvdata = dev_get_drvdata(dev);
> + int ret;
>
> - if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
> - clk_prepare_enable(drvdata->pclk);
> + ret = clk_prepare_enable(drvdata->pclk);
> + if (ret)
> + return ret;
>
> - if (drvdata && !IS_ERR(drvdata->atclk))
> - clk_prepare_enable(drvdata->atclk);
> - return 0;
> + ret = clk_prepare_enable(drvdata->atclk);
> + if (ret)
> + clk_disable_unprepare(drvdata->pclk);
> +
> + return ret;
> }
> #endif
>
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 6/9] coresight: Avoid enable programming clock duplicately
2025-06-09 17:14 ` Leo Yan
@ 2025-06-10 10:39 ` Anshuman Khandual
2025-06-10 12:03 ` Leo Yan
0 siblings, 1 reply; 24+ messages in thread
From: Anshuman Khandual @ 2025-06-10 10:39 UTC (permalink / raw)
To: Leo Yan, Suzuki K Poulose
Cc: Mike Leach, James Clark, Alexander Shishkin, Greg Kroah-Hartman,
coresight, linux-arm-kernel, linux-kernel
On 09/06/25 10:44 PM, Leo Yan wrote:
> On Mon, Jun 09, 2025 at 05:58:34PM +0100, Suzuki Kuruppassery Poulose wrote:
>
> [...]
>
>>> static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev)
>>> {
>>> - struct clk *pclk;
>>> + struct clk *pclk = NULL;
>>> - pclk = devm_clk_get_enabled(dev, "apb_pclk");
>>> - if (IS_ERR(pclk))
>>> - pclk = devm_clk_get_enabled(dev, "apb");
>>> + if (!dev_is_amba(dev)) {
>>> + pclk = devm_clk_get_enabled(dev, "apb_pclk");
>>> + if (IS_ERR(pclk))
>>> + pclk = devm_clk_get_enabled(dev, "apb");
>>
>> AMBA driver doesn't handle "apb" clock ? So we may need to retain that here
>> ?
>
> Here checks the condition "if (!dev_is_amba(dev))", it means the device
> is not an AMBA device (e.g., a platform device), the APB clock is
> enabled at here.
Just exit early for AMBA devices when 'pclk' clock is still NULL ?
if (dev_is_amba(dev))
return pclk;
>
> Otherwise, for a AMBA device, the AMBA bus layer will help to enable
> APB clock.
>
>> Otherwise looks good to me.
>>
>> Suzuki
>>> + }
>>> return pclk;
>>> }
>>>
>>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 6/9] coresight: Avoid enable programming clock duplicately
2025-06-10 10:39 ` Anshuman Khandual
@ 2025-06-10 12:03 ` Leo Yan
2025-06-24 4:43 ` Anshuman Khandual
0 siblings, 1 reply; 24+ messages in thread
From: Leo Yan @ 2025-06-10 12:03 UTC (permalink / raw)
To: Anshuman Khandual
Cc: Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel
On Tue, Jun 10, 2025 at 04:09:32PM +0530, Anshuman Khandual wrote:
>
>
> On 09/06/25 10:44 PM, Leo Yan wrote:
> > On Mon, Jun 09, 2025 at 05:58:34PM +0100, Suzuki Kuruppassery Poulose wrote:
> >
> > [...]
> >
> >>> static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev)
> >>> {
> >>> - struct clk *pclk;
> >>> + struct clk *pclk = NULL;
> >>> - pclk = devm_clk_get_enabled(dev, "apb_pclk");
> >>> - if (IS_ERR(pclk))
> >>> - pclk = devm_clk_get_enabled(dev, "apb");
> >>> + if (!dev_is_amba(dev)) {
> >>> + pclk = devm_clk_get_enabled(dev, "apb_pclk");
> >>> + if (IS_ERR(pclk))
> >>> + pclk = devm_clk_get_enabled(dev, "apb");
> >>
> >> AMBA driver doesn't handle "apb" clock ? So we may need to retain that here
> >> ?
> >
> > Here checks the condition "if (!dev_is_amba(dev))", it means the device
> > is not an AMBA device (e.g., a platform device), the APB clock is
> > enabled at here.
>
> Just exit early for AMBA devices when 'pclk' clock is still NULL ?
>
> if (dev_is_amba(dev))
> return pclk;
If it is an AMBA device, we should return a NULL pointer, as this
indicates that the APB clock is not managed by the CoreSight driver.
In this patch, I did not perform any refactoring and simply made a
straightforward changed. The refactoring is done in the patch 07, as
you suggested, where the function is refined as:
if (dev_is_amba(dev)) {
return NULL;
} else {
pclk = devm_clk_get_enabled(dev, "apb_pclk");
...
}
Would it be acceptable to keep this patch as it is?
Thanks,
Leo
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 4/9] coresight: Appropriately disable programming clocks
2025-06-09 16:38 ` Leo Yan
@ 2025-06-24 4:23 ` Anshuman Khandual
0 siblings, 0 replies; 24+ messages in thread
From: Anshuman Khandual @ 2025-06-24 4:23 UTC (permalink / raw)
To: Leo Yan, Suzuki K Poulose
Cc: Mike Leach, James Clark, Alexander Shishkin, Greg Kroah-Hartman,
coresight, linux-arm-kernel, linux-kernel
On 09/06/25 10:08 PM, Leo Yan wrote:
> On Mon, Jun 09, 2025 at 05:11:21PM +0100, Suzuki Kuruppassery Poulose wrote:
>> On 09/06/2025 17:00, Leo Yan wrote:
>>> Some CoreSight components have programming clocks (pclk) and are enabled
>>> using clk_get() and clk_prepare_enable(). However, in many cases, these
>>> clocks are not disabled when modules exit and only released by clk_put().
>>>
>>> To fix the issue, this commit refactors coresight_get_enable_apb_pclk()
>>> by replacing clk_get() and clk_prepare_enable() with
>>> devm_clk_get_enabled() for enabling APB clock. Callers are updated
>>> to reuse the returned error value.
>>>
>>> With the change, programming clocks are managed as resources in driver
>>> model layer, allowing clock cleanup to be handled automatically. As a
>>> result, manual cleanup operations are no longer needed and are removed
>>> from the Coresight drivers.
>>>
>>> Fixes: 73d779a03a76 ("coresight: etm4x: Change etm4_platform_driver driver for MMIO devices")
>>
>> This looks suspicious. This patch covers a lot of components, but the
>> above commit is only affecting ETMv4 ?
>
> Since commit 73d779a03a76 is the earliest patch that introduced the
> issue, it has been selected as the fix tag. We assume this will cover
> any subsequent changes that have the same issue.
Although I am not still sure about this patch actually requiring a
'Fixes:' tag as it just transitions into the device managed clocks
rather than fixing an existing issue. But choosing the first commit
makes sense as Leo has explained.
>
>> The patch as such looks good to me.
>
> Thanks for review!
>
>> Suzuki
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 4/9] coresight: Appropriately disable programming clocks
2025-06-09 16:00 ` [PATCH v3 4/9] coresight: Appropriately disable programming clocks Leo Yan
2025-06-09 16:11 ` Suzuki K Poulose
@ 2025-06-24 4:37 ` Anshuman Khandual
1 sibling, 0 replies; 24+ messages in thread
From: Anshuman Khandual @ 2025-06-24 4:37 UTC (permalink / raw)
To: Leo Yan, Suzuki K Poulose, Mike Leach, James Clark,
Alexander Shishkin, Greg Kroah-Hartman
Cc: coresight, linux-arm-kernel, linux-kernel
On 09/06/25 9:30 PM, Leo Yan wrote:
> Some CoreSight components have programming clocks (pclk) and are enabled
> using clk_get() and clk_prepare_enable(). However, in many cases, these
> clocks are not disabled when modules exit and only released by clk_put().
>
> To fix the issue, this commit refactors coresight_get_enable_apb_pclk()
> by replacing clk_get() and clk_prepare_enable() with
> devm_clk_get_enabled() for enabling APB clock. Callers are updated
> to reuse the returned error value.
>
> With the change, programming clocks are managed as resources in driver
> model layer, allowing clock cleanup to be handled automatically. As a
> result, manual cleanup operations are no longer needed and are removed
> from the Coresight drivers.
>
> Fixes: 73d779a03a76 ("coresight: etm4x: Change etm4_platform_driver driver for MMIO devices")
> Signed-off-by: Leo Yan <leo.yan@arm.com>
> ---
> drivers/hwtracing/coresight/coresight-catu.c | 9 ++-------
> drivers/hwtracing/coresight/coresight-cpu-debug.c | 6 +-----
> drivers/hwtracing/coresight/coresight-ctcu-core.c | 10 ++--------
> drivers/hwtracing/coresight/coresight-etm4x-core.c | 9 ++-------
> drivers/hwtracing/coresight/coresight-funnel.c | 6 +-----
> drivers/hwtracing/coresight/coresight-replicator.c | 6 +-----
> drivers/hwtracing/coresight/coresight-stm.c | 4 +---
> drivers/hwtracing/coresight/coresight-tmc-core.c | 4 +---
> drivers/hwtracing/coresight/coresight-tpiu.c | 4 +---
> include/linux/coresight.h | 16 +++-------------
> 10 files changed, 15 insertions(+), 59 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c
> index af2a55f0c907c392d092a50612b23c115a1b0f5f..4c345ff2cff141ea63c2220393e5fdd00c449ca6 100644
> --- a/drivers/hwtracing/coresight/coresight-catu.c
> +++ b/drivers/hwtracing/coresight/coresight-catu.c
> @@ -636,7 +636,7 @@ static int catu_platform_probe(struct platform_device *pdev)
>
> drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
> if (IS_ERR(drvdata->pclk))
> - return -ENODEV;
> + return PTR_ERR(drvdata->pclk);
>
> pm_runtime_get_noresume(&pdev->dev);
> pm_runtime_set_active(&pdev->dev);
> @@ -645,11 +645,8 @@ static int catu_platform_probe(struct platform_device *pdev)
> dev_set_drvdata(&pdev->dev, drvdata);
> ret = __catu_probe(&pdev->dev, res);
> pm_runtime_put(&pdev->dev);
> - if (ret) {
> + if (ret)
> pm_runtime_disable(&pdev->dev);
> - if (!IS_ERR_OR_NULL(drvdata->pclk))
> - clk_put(drvdata->pclk);
> - }
>
> return ret;
> }
> @@ -663,8 +660,6 @@ static void catu_platform_remove(struct platform_device *pdev)
>
> __catu_remove(&pdev->dev);
> pm_runtime_disable(&pdev->dev);
> - if (!IS_ERR_OR_NULL(drvdata->pclk))
> - clk_put(drvdata->pclk);
> }
>
> #ifdef CONFIG_PM
> diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c
> index a871d997330b09bdb741f35c59108b0b3252cc54..e39dfb886688e111eee95d4294f37fa85baccd14 100644
> --- a/drivers/hwtracing/coresight/coresight-cpu-debug.c
> +++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c
> @@ -699,7 +699,7 @@ static int debug_platform_probe(struct platform_device *pdev)
>
> drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
> if (IS_ERR(drvdata->pclk))
> - return -ENODEV;
> + return PTR_ERR(drvdata->pclk);
>
> dev_set_drvdata(&pdev->dev, drvdata);
> pm_runtime_get_noresume(&pdev->dev);
> @@ -710,8 +710,6 @@ static int debug_platform_probe(struct platform_device *pdev)
> if (ret) {
> pm_runtime_put_noidle(&pdev->dev);
> pm_runtime_disable(&pdev->dev);
> - if (!IS_ERR_OR_NULL(drvdata->pclk))
> - clk_put(drvdata->pclk);
> }
> return ret;
> }
> @@ -725,8 +723,6 @@ static void debug_platform_remove(struct platform_device *pdev)
>
> __debug_remove(&pdev->dev);
> pm_runtime_disable(&pdev->dev);
> - if (!IS_ERR_OR_NULL(drvdata->pclk))
> - clk_put(drvdata->pclk);
> }
>
> #ifdef CONFIG_ACPI
> diff --git a/drivers/hwtracing/coresight/coresight-ctcu-core.c b/drivers/hwtracing/coresight/coresight-ctcu-core.c
> index c6bafc96db963310b5e77a095953c83a172cfc7c..de279efe340581ceabfb9e1cd1e7fe4b5e4f826e 100644
> --- a/drivers/hwtracing/coresight/coresight-ctcu-core.c
> +++ b/drivers/hwtracing/coresight/coresight-ctcu-core.c
> @@ -209,7 +209,7 @@ static int ctcu_probe(struct platform_device *pdev)
>
> drvdata->apb_clk = coresight_get_enable_apb_pclk(dev);
> if (IS_ERR(drvdata->apb_clk))
> - return -ENODEV;
> + return PTR_ERR(drvdata->apb_clk);
>
> cfgs = of_device_get_match_data(dev);
> if (cfgs) {
> @@ -233,12 +233,8 @@ static int ctcu_probe(struct platform_device *pdev)
> desc.access = CSDEV_ACCESS_IOMEM(base);
>
> drvdata->csdev = coresight_register(&desc);
> - if (IS_ERR(drvdata->csdev)) {
> - if (!IS_ERR_OR_NULL(drvdata->apb_clk))
> - clk_put(drvdata->apb_clk);
> -
> + if (IS_ERR(drvdata->csdev))
> return PTR_ERR(drvdata->csdev);
> - }
>
> return 0;
> }
> @@ -275,8 +271,6 @@ static void ctcu_platform_remove(struct platform_device *pdev)
>
> ctcu_remove(pdev);
> pm_runtime_disable(&pdev->dev);
> - if (!IS_ERR_OR_NULL(drvdata->apb_clk))
> - clk_put(drvdata->apb_clk);
> }
>
> #ifdef CONFIG_PM
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> index 205121c14d72ec2f6a193dccb94b7cfd5c314e26..1915da95b93d953a61778a71b4880c87b91fe17a 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -2303,14 +2303,12 @@ static int etm4_probe_platform_dev(struct platform_device *pdev)
>
> drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
> if (IS_ERR(drvdata->pclk))
> - return -ENODEV;
> + return PTR_ERR(drvdata->pclk);
>
> if (res) {
> drvdata->base = devm_ioremap_resource(&pdev->dev, res);
> - if (IS_ERR(drvdata->base)) {
> - clk_put(drvdata->pclk);
> + if (IS_ERR(drvdata->base))
> return PTR_ERR(drvdata->base);
> - }
> }
>
> dev_set_drvdata(&pdev->dev, drvdata);
> @@ -2417,9 +2415,6 @@ static void etm4_remove_platform_dev(struct platform_device *pdev)
> if (drvdata)
> etm4_remove_dev(drvdata);
> pm_runtime_disable(&pdev->dev);
> -
> - if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
> - clk_put(drvdata->pclk);
> }
>
> static const struct amba_id etm4_ids[] = {
> diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
> index b1922dbe9292b02c91ca5730998e59ecdb08fdc7..36fc4e991458c112521c4261d73f3e58e9a3f995 100644
> --- a/drivers/hwtracing/coresight/coresight-funnel.c
> +++ b/drivers/hwtracing/coresight/coresight-funnel.c
> @@ -240,7 +240,7 @@ static int funnel_probe(struct device *dev, struct resource *res)
>
> drvdata->pclk = coresight_get_enable_apb_pclk(dev);
> if (IS_ERR(drvdata->pclk))
> - return -ENODEV;
> + return PTR_ERR(drvdata->pclk);
>
> /*
> * Map the device base for dynamic-funnel, which has been
> @@ -284,8 +284,6 @@ static int funnel_probe(struct device *dev, struct resource *res)
> out_disable_clk:
> if (ret && !IS_ERR_OR_NULL(drvdata->atclk))
> clk_disable_unprepare(drvdata->atclk);
> - if (ret && !IS_ERR_OR_NULL(drvdata->pclk))
> - clk_disable_unprepare(drvdata->pclk);
> return ret;
> }
>
> @@ -355,8 +353,6 @@ static void funnel_platform_remove(struct platform_device *pdev)
>
> funnel_remove(&pdev->dev);
> pm_runtime_disable(&pdev->dev);
> - if (!IS_ERR_OR_NULL(drvdata->pclk))
> - clk_put(drvdata->pclk);
> }
>
> static const struct of_device_id funnel_match[] = {
> diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
> index 06efd2b01a0f71620eac71166567d14655b58403..6dd24eb10a94b0eb28f4f27afab845227e22b96c 100644
> --- a/drivers/hwtracing/coresight/coresight-replicator.c
> +++ b/drivers/hwtracing/coresight/coresight-replicator.c
> @@ -247,7 +247,7 @@ static int replicator_probe(struct device *dev, struct resource *res)
>
> drvdata->pclk = coresight_get_enable_apb_pclk(dev);
> if (IS_ERR(drvdata->pclk))
> - return -ENODEV;
> + return PTR_ERR(drvdata->pclk);
>
> /*
> * Map the device base for dynamic-replicator, which has been
> @@ -296,8 +296,6 @@ static int replicator_probe(struct device *dev, struct resource *res)
> out_disable_clk:
> if (ret && !IS_ERR_OR_NULL(drvdata->atclk))
> clk_disable_unprepare(drvdata->atclk);
> - if (ret && !IS_ERR_OR_NULL(drvdata->pclk))
> - clk_disable_unprepare(drvdata->pclk);
> return ret;
> }
>
> @@ -335,8 +333,6 @@ static void replicator_platform_remove(struct platform_device *pdev)
>
> replicator_remove(&pdev->dev);
> pm_runtime_disable(&pdev->dev);
> - if (!IS_ERR_OR_NULL(drvdata->pclk))
> - clk_put(drvdata->pclk);
> }
>
> #ifdef CONFIG_PM
> diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
> index e45c6c7204b4491e0f879bc7d5d445aa1d3118be..88ee453b2815444a550a2b932b28367eb93336b8 100644
> --- a/drivers/hwtracing/coresight/coresight-stm.c
> +++ b/drivers/hwtracing/coresight/coresight-stm.c
> @@ -851,7 +851,7 @@ static int __stm_probe(struct device *dev, struct resource *res)
>
> drvdata->pclk = coresight_get_enable_apb_pclk(dev);
> if (IS_ERR(drvdata->pclk))
> - return -ENODEV;
> + return PTR_ERR(drvdata->pclk);
> dev_set_drvdata(dev, drvdata);
>
> base = devm_ioremap_resource(dev, res);
> @@ -1033,8 +1033,6 @@ static void stm_platform_remove(struct platform_device *pdev)
>
> __stm_remove(&pdev->dev);
> pm_runtime_disable(&pdev->dev);
> - if (!IS_ERR_OR_NULL(drvdata->pclk))
> - clk_put(drvdata->pclk);
> }
>
> #ifdef CONFIG_ACPI
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
> index 0b5e7635a084d226619e69189a2ecbaff754ec43..e867198b03e82892da7312c9dc1c69676602c598 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
> @@ -991,7 +991,7 @@ static int tmc_platform_probe(struct platform_device *pdev)
>
> drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
> if (IS_ERR(drvdata->pclk))
> - return -ENODEV;
> + return PTR_ERR(drvdata->pclk);
>
> dev_set_drvdata(&pdev->dev, drvdata);
> pm_runtime_get_noresume(&pdev->dev);
> @@ -1015,8 +1015,6 @@ static void tmc_platform_remove(struct platform_device *pdev)
>
> __tmc_remove(&pdev->dev);
> pm_runtime_disable(&pdev->dev);
> - if (!IS_ERR_OR_NULL(drvdata->pclk))
> - clk_put(drvdata->pclk);
> }
>
> #ifdef CONFIG_PM
> diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
> index 3e01592884280819c16398cbb5e09cbaee5d3efb..b2559c6fac6d2f02e0038e583cd324d7165c5aee 100644
> --- a/drivers/hwtracing/coresight/coresight-tpiu.c
> +++ b/drivers/hwtracing/coresight/coresight-tpiu.c
> @@ -153,7 +153,7 @@ static int __tpiu_probe(struct device *dev, struct resource *res)
>
> drvdata->pclk = coresight_get_enable_apb_pclk(dev);
> if (IS_ERR(drvdata->pclk))
> - return -ENODEV;
> + return PTR_ERR(drvdata->pclk);
> dev_set_drvdata(dev, drvdata);
>
> /* Validity for the resource is already checked by the AMBA core */
> @@ -293,8 +293,6 @@ static void tpiu_platform_remove(struct platform_device *pdev)
>
> __tpiu_remove(&pdev->dev);
> pm_runtime_disable(&pdev->dev);
> - if (!IS_ERR_OR_NULL(drvdata->pclk))
> - clk_put(drvdata->pclk);
> }
>
> #ifdef CONFIG_ACPI
> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> index 4ac65c68bbf44b98db22c3dad2d83a224ce5278e..dd2b4cc7a2b70cf060a3207548fe80e3824c489f 100644
> --- a/include/linux/coresight.h
> +++ b/include/linux/coresight.h
> @@ -480,26 +480,16 @@ static inline bool is_coresight_device(void __iomem *base)
> * Returns:
> *
> * clk - Clock is found and enabled
> - * NULL - clock is not found
> * ERROR - Clock is found but failed to enable
> */
> static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev)
> {
> struct clk *pclk;
> - int ret;
>
> - pclk = clk_get(dev, "apb_pclk");
> - if (IS_ERR(pclk)) {
> - pclk = clk_get(dev, "apb");
> - if (IS_ERR(pclk))
> - return NULL;
> - }
> + pclk = devm_clk_get_enabled(dev, "apb_pclk");
> + if (IS_ERR(pclk))
> + pclk = devm_clk_get_enabled(dev, "apb");
>
> - ret = clk_prepare_enable(pclk);
> - if (ret) {
> - clk_put(pclk);
> - return ERR_PTR(ret);
> - }
> return pclk;
> }
>
>
LGTM.
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 6/9] coresight: Avoid enable programming clock duplicately
2025-06-10 12:03 ` Leo Yan
@ 2025-06-24 4:43 ` Anshuman Khandual
0 siblings, 0 replies; 24+ messages in thread
From: Anshuman Khandual @ 2025-06-24 4:43 UTC (permalink / raw)
To: Leo Yan
Cc: Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel
On 10/06/25 5:33 PM, Leo Yan wrote:
> On Tue, Jun 10, 2025 at 04:09:32PM +0530, Anshuman Khandual wrote:
>>
>>
>> On 09/06/25 10:44 PM, Leo Yan wrote:
>>> On Mon, Jun 09, 2025 at 05:58:34PM +0100, Suzuki Kuruppassery Poulose wrote:
>>>
>>> [...]
>>>
>>>>> static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev)
>>>>> {
>>>>> - struct clk *pclk;
>>>>> + struct clk *pclk = NULL;
>>>>> - pclk = devm_clk_get_enabled(dev, "apb_pclk");
>>>>> - if (IS_ERR(pclk))
>>>>> - pclk = devm_clk_get_enabled(dev, "apb");
>>>>> + if (!dev_is_amba(dev)) {
>>>>> + pclk = devm_clk_get_enabled(dev, "apb_pclk");
>>>>> + if (IS_ERR(pclk))
>>>>> + pclk = devm_clk_get_enabled(dev, "apb");
>>>>
>>>> AMBA driver doesn't handle "apb" clock ? So we may need to retain that here
>>>> ?
>>>
>>> Here checks the condition "if (!dev_is_amba(dev))", it means the device
>>> is not an AMBA device (e.g., a platform device), the APB clock is
>>> enabled at here.
>>
>> Just exit early for AMBA devices when 'pclk' clock is still NULL ?
>>
>> if (dev_is_amba(dev))
>> return pclk;
>
> If it is an AMBA device, we should return a NULL pointer, as this
> indicates that the APB clock is not managed by the CoreSight driver.
>
> In this patch, I did not perform any refactoring and simply made a
> straightforward changed. The refactoring is done in the patch 07, as
> you suggested, where the function is refined as:
>
> if (dev_is_amba(dev)) {
> return NULL;
> } else {
> pclk = devm_clk_get_enabled(dev, "apb_pclk");
> ...
> }
>
> Would it be acceptable to keep this patch as it is?
Agreed. Let's avoid the churn here as the refactoring happens
later anyway.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 6/9] coresight: Avoid enable programming clock duplicately
2025-06-09 16:00 ` [PATCH v3 6/9] coresight: Avoid enable programming clock duplicately Leo Yan
2025-06-09 16:58 ` Suzuki K Poulose
@ 2025-06-24 5:11 ` Anshuman Khandual
1 sibling, 0 replies; 24+ messages in thread
From: Anshuman Khandual @ 2025-06-24 5:11 UTC (permalink / raw)
To: Leo Yan, Suzuki K Poulose, Mike Leach, James Clark,
Alexander Shishkin, Greg Kroah-Hartman
Cc: coresight, linux-arm-kernel, linux-kernel
On 09/06/25 9:30 PM, Leo Yan wrote:
> The programming clock is enabled by AMBA bus driver before a dynamic
> probe. As a result, a CoreSight driver may redundantly enable the same
> clock.
>
> To avoid this, add a check for device type and skip enabling the
> programming clock for AMBA devices. The returned NULL pointer will be
> tolerated by the drivers.
>
> Fixes: 73d779a03a76 ("coresight: etm4x: Change etm4_platform_driver driver for MMIO devices")
> Signed-off-by: Leo Yan <leo.yan@arm.com>
> ---
> include/linux/coresight.h | 11 +++++++----
> 1 file changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> index dd2b4cc7a2b70cf060a3207548fe80e3824c489f..9afa1f76c78a3347e54d94fe9a9ebed72e3fff8e 100644
> --- a/include/linux/coresight.h
> +++ b/include/linux/coresight.h
> @@ -480,15 +480,18 @@ static inline bool is_coresight_device(void __iomem *base)
> * Returns:
> *
> * clk - Clock is found and enabled
> + * NULL - Clock is not needed as it is managed by the AMBA bus driver
> * ERROR - Clock is found but failed to enable
> */
> static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev)
> {
> - struct clk *pclk;
> + struct clk *pclk = NULL;
>
> - pclk = devm_clk_get_enabled(dev, "apb_pclk");
> - if (IS_ERR(pclk))
> - pclk = devm_clk_get_enabled(dev, "apb");
> + if (!dev_is_amba(dev)) {
> + pclk = devm_clk_get_enabled(dev, "apb_pclk");
> + if (IS_ERR(pclk))
> + pclk = devm_clk_get_enabled(dev, "apb");
> + }
>
> return pclk;
> }
>
LGTM
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 7/9] coresight: Consolidate clock enabling
2025-06-09 16:00 ` [PATCH v3 7/9] coresight: Consolidate clock enabling Leo Yan
@ 2025-06-24 5:44 ` Anshuman Khandual
2025-06-24 10:08 ` Leo Yan
0 siblings, 1 reply; 24+ messages in thread
From: Anshuman Khandual @ 2025-06-24 5:44 UTC (permalink / raw)
To: Leo Yan, Suzuki K Poulose, Mike Leach, James Clark,
Alexander Shishkin, Greg Kroah-Hartman
Cc: coresight, linux-arm-kernel, linux-kernel
On 09/06/25 9:30 PM, Leo Yan wrote:
> CoreSight drivers enable pclk and atclk conditionally. For example,
> pclk is only enabled in the static probe, while atclk is an optional
> clock that it is enabled for both dynamic and static probes, if it is
> present. In the current CoreSight drivers, these two clocks are
> initialized separately. This causes complex and duplicate codes.
>
> This patch consolidates clock enabling into a central place. It renames
> coresight_get_enable_apb_pclk() to coresight_get_enable_clocks() and
> encapsulates clock initialization logic:
>
> - If a clock is initialized successfully, its clock pointer is assigned
> to the double pointer passed as an argument.
> - If pclk is skipped for an AMBA device, or if atclk is not found, the
> corresponding double pointer is set to NULL. The function returns
> Success (0) to guide callers can proceed with no error.
> - Otherwise, an error number is returned for failures.
>
> The function became complex, move it from the header to the CoreSight
> core layer and the symbol is exported. Added comments for recording
> details.
>
> CoreSight drivers are refined so that clocks are initialized in one go.
> As a result, driver data no longer needs to be allocated separately in
> the static and dynamic probes. Moved the allocation into a low-level
> function to avoid code duplication.
But why should this change be included here in this patch that
consolidates pclk and atclk clock initialization ? Should this
be done in a separate patch instead ?
>
> Suggested-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> Signed-off-by: Leo Yan <leo.yan@arm.com>
> ---
> drivers/hwtracing/coresight/coresight-catu.c | 30 +++++----------
> drivers/hwtracing/coresight/coresight-core.c | 45 ++++++++++++++++++++++
> drivers/hwtracing/coresight/coresight-cpu-debug.c | 29 ++++++--------
> drivers/hwtracing/coresight/coresight-ctcu-core.c | 8 ++--
> drivers/hwtracing/coresight/coresight-etm4x-core.c | 11 ++----
> drivers/hwtracing/coresight/coresight-funnel.c | 11 ++----
> drivers/hwtracing/coresight/coresight-replicator.c | 11 ++----
> drivers/hwtracing/coresight/coresight-stm.c | 9 ++---
> drivers/hwtracing/coresight/coresight-tmc-core.c | 30 +++++----------
> drivers/hwtracing/coresight/coresight-tpiu.c | 10 ++---
> include/linux/coresight.h | 23 +----------
> 11 files changed, 101 insertions(+), 116 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c
> index 4c345ff2cff141ea63c2220393e5fdd00c449ca6..a3ccb7034ae14d7339bc2549bccadf11e28c45e2 100644
> --- a/drivers/hwtracing/coresight/coresight-catu.c
> +++ b/drivers/hwtracing/coresight/coresight-catu.c
> @@ -515,14 +515,20 @@ static int __catu_probe(struct device *dev, struct resource *res)
> {
> int ret = 0;
> u32 dma_mask;
> - struct catu_drvdata *drvdata = dev_get_drvdata(dev);
> + struct catu_drvdata *drvdata;
> struct coresight_desc catu_desc;
> struct coresight_platform_data *pdata = NULL;
> void __iomem *base;
>
> - drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
> - if (IS_ERR(drvdata->atclk))
> - return PTR_ERR(drvdata->atclk);
> + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
> + if (!drvdata)
> + return -ENOMEM;
> +
> + dev_set_drvdata(dev, drvdata);
> +
> + ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk);
> + if (ret)
> + return ret;
>
> catu_desc.name = coresight_alloc_device_name(&catu_devs, dev);
> if (!catu_desc.name)
> @@ -580,14 +586,8 @@ static int __catu_probe(struct device *dev, struct resource *res)
>
> static int catu_probe(struct amba_device *adev, const struct amba_id *id)
> {
> - struct catu_drvdata *drvdata;
> int ret;
>
> - drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL);
> - if (!drvdata)
> - return -ENOMEM;
> -
> - amba_set_drvdata(adev, drvdata);
> ret = __catu_probe(&adev->dev, &adev->res);
> if (!ret)
> pm_runtime_put(&adev->dev);
> @@ -627,22 +627,12 @@ static struct amba_driver catu_driver = {
> static int catu_platform_probe(struct platform_device *pdev)
> {
> struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> - struct catu_drvdata *drvdata;
> int ret = 0;
>
> - drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
> - if (!drvdata)
> - return -ENOMEM;
> -
> - drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
> - if (IS_ERR(drvdata->pclk))
> - return PTR_ERR(drvdata->pclk);
> -
> pm_runtime_get_noresume(&pdev->dev);
> pm_runtime_set_active(&pdev->dev);
> pm_runtime_enable(&pdev->dev);
>
> - dev_set_drvdata(&pdev->dev, drvdata);
> ret = __catu_probe(&pdev->dev, res);
> pm_runtime_put(&pdev->dev);
> if (ret)
> diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
> index fa758cc21827552a5c97b6bdd05d22dec4994b22..f9cc240e7c259fdb7cb3ee321825b44079a07b69 100644
> --- a/drivers/hwtracing/coresight/coresight-core.c
> +++ b/drivers/hwtracing/coresight/coresight-core.c
> @@ -1698,6 +1698,51 @@ int coresight_etm_get_trace_id(struct coresight_device *csdev, enum cs_mode mode
> }
> EXPORT_SYMBOL_GPL(coresight_etm_get_trace_id);
>
> +/*
> + * Attempt to find and enable programming clock (pclk) and trace clock (atclk)
> + * for the given device.
> + *
> + * The AMBA bus driver will cover the pclk, to avoid duplicate operations,
> + * skip to get and enable the pclk for an AMBA device.
> + *
> + * atclk is an optional clock, it will be only enabled when it is existed.
> + * Otherwise, a NULL pointer will be returned to caller.
> + *
> + * Returns: '0' on Success; Error code otherwise.
> + */
> +int coresight_get_enable_clocks(struct device *dev, struct clk **pclk,
> + struct clk **atclk)
Moving this helper function here does make sense.
> +{
> + WARN_ON(!pclk);
That is because pclk will be populated in all possible scenarios
including the one assigned as NULL - hence it needs to have been
allocated.
> +
> + if (dev_is_amba(dev)) {
> + /* Don't enable pclk for an AMBA device */
> + *pclk = NULL;
> + } else {
> + /*
> + * "apb_pclk" is the default clock name for an Arm Primecell
> + * peripheral, while "apb" is used only by the CTCU driver.
> + *
> + * For easier maintenance, CoreSight drivers should use
> + * "apb_pclk" as the programming clock name.
> + */
> + *pclk = devm_clk_get_enabled(dev, "apb_pclk");
> + if (IS_ERR(*pclk))
> + *pclk = devm_clk_get_enabled(dev, "apb");
> + if (IS_ERR(*pclk))
> + return PTR_ERR(*pclk);
> + }
> +
> + if (atclk) {
But an allocated atclk indicates need for atclk clock init instead.
Probably a 'which all clocks' flag based approach might been better ?
But I guess this proposal will create less code churn.
> + *atclk = devm_clk_get_optional_enabled(dev, "atclk");
> + if (IS_ERR(*atclk))
> + return PTR_ERR(*atclk);
> + }
atclk when requested - either will have a valid clock or an error
pointer but never a NULL pointer unlike the pclk clock ?
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(coresight_get_enable_clocks);
> +
> MODULE_LICENSE("GPL v2");
> MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
> MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
> diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c
> index e39dfb886688e111eee95d4294f37fa85baccd14..3edfb5d3d02056afcaab4da575d1101c68aeac80 100644
> --- a/drivers/hwtracing/coresight/coresight-cpu-debug.c
> +++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c
> @@ -562,10 +562,20 @@ static void debug_func_exit(void)
>
> static int __debug_probe(struct device *dev, struct resource *res)
> {
> - struct debug_drvdata *drvdata = dev_get_drvdata(dev);
> + struct debug_drvdata *drvdata;
> void __iomem *base;
> int ret;
>
> + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
> + if (!drvdata)
> + return -ENOMEM;
> +
> + dev_set_drvdata(dev, drvdata);
> +
> + ret = coresight_get_enable_clocks(dev, &drvdata->pclk, NULL);
> + if (ret)
> + return ret;
> +
> drvdata->cpu = coresight_get_cpu(dev);
> if (drvdata->cpu < 0)
> return drvdata->cpu;
> @@ -625,13 +635,6 @@ static int __debug_probe(struct device *dev, struct resource *res)
>
> static int debug_probe(struct amba_device *adev, const struct amba_id *id)
> {
> - struct debug_drvdata *drvdata;
> -
> - drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL);
> - if (!drvdata)
> - return -ENOMEM;
> -
> - amba_set_drvdata(adev, drvdata);
> return __debug_probe(&adev->dev, &adev->res);
> }
>
> @@ -690,18 +693,8 @@ static struct amba_driver debug_driver = {
> static int debug_platform_probe(struct platform_device *pdev)
> {
> struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> - struct debug_drvdata *drvdata;
> int ret = 0;
>
> - drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
> - if (!drvdata)
> - return -ENOMEM;
> -
> - drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
> - if (IS_ERR(drvdata->pclk))
> - return PTR_ERR(drvdata->pclk);
> -
> - dev_set_drvdata(&pdev->dev, drvdata);
> pm_runtime_get_noresume(&pdev->dev);
> pm_runtime_set_active(&pdev->dev);
> pm_runtime_enable(&pdev->dev);
> diff --git a/drivers/hwtracing/coresight/coresight-ctcu-core.c b/drivers/hwtracing/coresight/coresight-ctcu-core.c
> index de279efe340581ceabfb9e1cd1e7fe4b5e4f826e..75b5114ef652e4a47c53fbd2b7811c1bab575645 100644
> --- a/drivers/hwtracing/coresight/coresight-ctcu-core.c
> +++ b/drivers/hwtracing/coresight/coresight-ctcu-core.c
> @@ -188,7 +188,7 @@ static int ctcu_probe(struct platform_device *pdev)
> const struct ctcu_config *cfgs;
> struct ctcu_drvdata *drvdata;
> void __iomem *base;
> - int i;
> + int i, ret;
>
> desc.name = coresight_alloc_device_name(&ctcu_devs, dev);
> if (!desc.name)
> @@ -207,9 +207,9 @@ static int ctcu_probe(struct platform_device *pdev)
> if (IS_ERR(base))
> return PTR_ERR(base);
>
> - drvdata->apb_clk = coresight_get_enable_apb_pclk(dev);
> - if (IS_ERR(drvdata->apb_clk))
> - return PTR_ERR(drvdata->apb_clk);
> + ret = coresight_get_enable_clocks(dev, &drvdata->apb_clk, NULL);
> + if (ret)
> + return ret;
>
> cfgs = of_device_get_match_data(dev);
> if (cfgs) {
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> index 1915da95b93d953a61778a71b4880c87b91fe17a..a742466ad0e14d2ceeeccddec5bba4f2160793c2 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -2211,13 +2211,14 @@ static int etm4_probe(struct device *dev)
> struct csdev_access access = { 0 };
> struct etm4_init_arg init_arg = { 0 };
> struct etm4_init_arg *delayed;
> + int ret;
>
> if (WARN_ON(!drvdata))
> return -ENOMEM;
>
> - drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
> - if (IS_ERR(drvdata->atclk))
> - return PTR_ERR(drvdata->atclk);
> + ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk);
> + if (ret)
> + return ret;
>
> if (pm_save_enable == PARAM_PM_SAVE_FIRMWARE)
> pm_save_enable = coresight_loses_context_with_cpu(dev) ?
> @@ -2301,10 +2302,6 @@ static int etm4_probe_platform_dev(struct platform_device *pdev)
> if (!drvdata)
> return -ENOMEM;
>
> - drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
> - if (IS_ERR(drvdata->pclk))
> - return PTR_ERR(drvdata->pclk);
> -
> if (res) {
> drvdata->base = devm_ioremap_resource(&pdev->dev, res);
> if (IS_ERR(drvdata->base))
> diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
> index b044a4125310ba4f8c88df295ec3684ab266682f..02e0dc678a32c3b1f32fc955bf8871142e3412e1 100644
> --- a/drivers/hwtracing/coresight/coresight-funnel.c
> +++ b/drivers/hwtracing/coresight/coresight-funnel.c
> @@ -217,6 +217,7 @@ static int funnel_probe(struct device *dev, struct resource *res)
> struct coresight_platform_data *pdata = NULL;
> struct funnel_drvdata *drvdata;
> struct coresight_desc desc = { 0 };
> + int ret;
>
> if (is_of_node(dev_fwnode(dev)) &&
> of_device_is_compatible(dev->of_node, "arm,coresight-funnel"))
> @@ -230,13 +231,9 @@ static int funnel_probe(struct device *dev, struct resource *res)
> if (!drvdata)
> return -ENOMEM;
>
> - drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
> - if (IS_ERR(drvdata->atclk))
> - return PTR_ERR(drvdata->atclk);
> -
> - drvdata->pclk = coresight_get_enable_apb_pclk(dev);
> - if (IS_ERR(drvdata->pclk))
> - return PTR_ERR(drvdata->pclk);
> + ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk);
> + if (ret)
> + return ret;
>
> /*
> * Map the device base for dynamic-funnel, which has been
> diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
> index 9e8bd36e7a9a2fd061f41c56242ac2b11549daf5..f1bbd12e63e0c130f945d8df34fb2334bd21336f 100644
> --- a/drivers/hwtracing/coresight/coresight-replicator.c
> +++ b/drivers/hwtracing/coresight/coresight-replicator.c
> @@ -223,6 +223,7 @@ static int replicator_probe(struct device *dev, struct resource *res)
> struct replicator_drvdata *drvdata;
> struct coresight_desc desc = { 0 };
> void __iomem *base;
> + int ret;
>
> if (is_of_node(dev_fwnode(dev)) &&
> of_device_is_compatible(dev->of_node, "arm,coresight-replicator"))
> @@ -237,13 +238,9 @@ static int replicator_probe(struct device *dev, struct resource *res)
> if (!drvdata)
> return -ENOMEM;
>
> - drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
> - if (IS_ERR(drvdata->atclk))
> - return PTR_ERR(drvdata->atclk);
> -
> - drvdata->pclk = coresight_get_enable_apb_pclk(dev);
> - if (IS_ERR(drvdata->pclk))
> - return PTR_ERR(drvdata->pclk);
> + ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk);
> + if (ret)
> + return ret;
>
> /*
> * Map the device base for dynamic-replicator, which has been
> diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
> index 57fbe3ad0fb20501d4e7e5c478d1e56e98685c40..a931282ec0eaf1b2a5db8ccc8f21789441cd634d 100644
> --- a/drivers/hwtracing/coresight/coresight-stm.c
> +++ b/drivers/hwtracing/coresight/coresight-stm.c
> @@ -842,13 +842,10 @@ static int __stm_probe(struct device *dev, struct resource *res)
> if (!drvdata)
> return -ENOMEM;
>
> - drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
> - if (IS_ERR(drvdata->atclk))
> - return PTR_ERR(drvdata->atclk);
> + ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk);
> + if (ret)
> + return ret;
>
> - drvdata->pclk = coresight_get_enable_apb_pclk(dev);
> - if (IS_ERR(drvdata->pclk))
> - return PTR_ERR(drvdata->pclk);
> dev_set_drvdata(dev, drvdata);
>
> base = devm_ioremap_resource(dev, res);
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
> index e867198b03e82892da7312c9dc1c69676602c598..e5ab4a0323354d826c831f68c71d81808cbcd8ff 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
> @@ -785,13 +785,19 @@ static int __tmc_probe(struct device *dev, struct resource *res)
> u32 devid;
> void __iomem *base;
> struct coresight_platform_data *pdata = NULL;
> - struct tmc_drvdata *drvdata = dev_get_drvdata(dev);
> + struct tmc_drvdata *drvdata;
> struct coresight_desc desc = { 0 };
> struct coresight_dev_list *dev_list = NULL;
>
> - drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
> - if (IS_ERR(drvdata->atclk))
> - return PTR_ERR(drvdata->atclk);
> + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
> + if (!drvdata)
> + return -ENOMEM;
> +
> + dev_set_drvdata(dev, drvdata);
> +
> + ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk);
> + if (ret)
> + return ret;
>
> ret = -ENOMEM;
>
> @@ -898,14 +904,8 @@ static int __tmc_probe(struct device *dev, struct resource *res)
>
> static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
> {
> - struct tmc_drvdata *drvdata;
> int ret;
>
> - drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL);
> - if (!drvdata)
> - return -ENOMEM;
> -
> - amba_set_drvdata(adev, drvdata);
> ret = __tmc_probe(&adev->dev, &adev->res);
> if (!ret)
> pm_runtime_put(&adev->dev);
> @@ -982,18 +982,8 @@ static struct amba_driver tmc_driver = {
> static int tmc_platform_probe(struct platform_device *pdev)
> {
> struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> - struct tmc_drvdata *drvdata;
> int ret = 0;
>
> - drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
> - if (!drvdata)
> - return -ENOMEM;
> -
> - drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
> - if (IS_ERR(drvdata->pclk))
> - return PTR_ERR(drvdata->pclk);
> -
> - dev_set_drvdata(&pdev->dev, drvdata);
> pm_runtime_get_noresume(&pdev->dev);
> pm_runtime_set_active(&pdev->dev);
> pm_runtime_enable(&pdev->dev);
> diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
> index 8d6179c83e5d3194d1f90e10c88fcc1faccf0cd7..5e47d761e1c4e99072eeb492c1eac7dd4285a591 100644
> --- a/drivers/hwtracing/coresight/coresight-tpiu.c
> +++ b/drivers/hwtracing/coresight/coresight-tpiu.c
> @@ -132,6 +132,7 @@ static int __tpiu_probe(struct device *dev, struct resource *res)
> struct coresight_platform_data *pdata = NULL;
> struct tpiu_drvdata *drvdata;
> struct coresight_desc desc = { 0 };
> + int ret;
>
> desc.name = coresight_alloc_device_name(&tpiu_devs, dev);
> if (!desc.name)
> @@ -143,13 +144,10 @@ static int __tpiu_probe(struct device *dev, struct resource *res)
>
> spin_lock_init(&drvdata->spinlock);
>
> - drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk");
> - if (IS_ERR(drvdata->atclk))
> - return PTR_ERR(drvdata->atclk);
> + ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk);
> + if (ret)
> + return ret;
>
> - drvdata->pclk = coresight_get_enable_apb_pclk(dev);
> - if (IS_ERR(drvdata->pclk))
> - return PTR_ERR(drvdata->pclk);
> dev_set_drvdata(dev, drvdata);
>
> /* Validity for the resource is already checked by the AMBA core */
> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> index 9afa1f76c78a3347e54d94fe9a9ebed72e3fff8e..96cc814c1886f02bf802918b3ccb457b245bdbd6 100644
> --- a/include/linux/coresight.h
> +++ b/include/linux/coresight.h
> @@ -474,27 +474,6 @@ static inline bool is_coresight_device(void __iomem *base)
> return cid == CORESIGHT_CID;
> }
>
> -/*
> - * Attempt to find and enable "APB clock" for the given device
> - *
> - * Returns:
> - *
> - * clk - Clock is found and enabled
> - * NULL - Clock is not needed as it is managed by the AMBA bus driver
> - * ERROR - Clock is found but failed to enable
> - */
> -static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev)
> -{
> - struct clk *pclk = NULL;
> -
> - if (!dev_is_amba(dev)) {
> - pclk = devm_clk_get_enabled(dev, "apb_pclk");
> - if (IS_ERR(pclk))
> - pclk = devm_clk_get_enabled(dev, "apb");
> - }
> -
> - return pclk;
> -}
>
> #define CORESIGHT_PIDRn(i) (0xFE0 + ((i) * 4))
>
> @@ -726,4 +705,6 @@ void coresight_remove_driver(struct amba_driver *amba_drv,
> struct platform_driver *pdev_drv);
> int coresight_etm_get_trace_id(struct coresight_device *csdev, enum cs_mode mode,
> struct coresight_device *sink);
> +int coresight_get_enable_clocks(struct device *dev, struct clk **pclk,
> + struct clk **atclk);
> #endif /* _LINUX_COREISGHT_H */
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 7/9] coresight: Consolidate clock enabling
2025-06-24 5:44 ` Anshuman Khandual
@ 2025-06-24 10:08 ` Leo Yan
0 siblings, 0 replies; 24+ messages in thread
From: Leo Yan @ 2025-06-24 10:08 UTC (permalink / raw)
To: Anshuman Khandual
Cc: Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
Greg Kroah-Hartman, coresight, linux-arm-kernel, linux-kernel
On Tue, Jun 24, 2025 at 11:14:17AM +0530, Anshuman Khandual wrote:
[...]
> > CoreSight drivers are refined so that clocks are initialized in one go.
> > As a result, driver data no longer needs to be allocated separately in
> > the static and dynamic probes. Moved the allocation into a low-level
> > function to avoid code duplication.
>
> But why should this change be included here in this patch that
> consolidates pclk and atclk clock initialization ? Should this
> be done in a separate patch instead ?
Good point. It indeed we can divide into two smaller patches, one is
for clock consolidations, and another patch is for refining driver data
allocation.
I will do this in next spin.
> > +/*
> > + * Attempt to find and enable programming clock (pclk) and trace clock (atclk)
> > + * for the given device.
> > + *
> > + * The AMBA bus driver will cover the pclk, to avoid duplicate operations,
> > + * skip to get and enable the pclk for an AMBA device.
> > + *
> > + * atclk is an optional clock, it will be only enabled when it is existed.
> > + * Otherwise, a NULL pointer will be returned to caller.
> > + *
> > + * Returns: '0' on Success; Error code otherwise.
> > + */
> > +int coresight_get_enable_clocks(struct device *dev, struct clk **pclk,
> > + struct clk **atclk)
> Moving this helper function here does make sense.
>
> > +{
> > + WARN_ON(!pclk);
>
> That is because pclk will be populated in all possible scenarios
> including the one assigned as NULL - hence it needs to have been
> allocated.
> > +
> > + if (dev_is_amba(dev)) {
> > + /* Don't enable pclk for an AMBA device */
> > + *pclk = NULL;
> > + } else {
> > + /*
> > + * "apb_pclk" is the default clock name for an Arm Primecell
> > + * peripheral, while "apb" is used only by the CTCU driver.
> > + *
> > + * For easier maintenance, CoreSight drivers should use
> > + * "apb_pclk" as the programming clock name.
> > + */
> > + *pclk = devm_clk_get_enabled(dev, "apb_pclk");
> > + if (IS_ERR(*pclk))
> > + *pclk = devm_clk_get_enabled(dev, "apb");
> > + if (IS_ERR(*pclk))
> > + return PTR_ERR(*pclk);
> > + }
> > +
> > + if (atclk) {
>
> But an allocated atclk indicates need for atclk clock init instead.
To be clear, we strictly follow up DT binding doc, atclk clock is
always optional. For a atclk pointer:
- If atclk is NULL: the driver does not require atclk at all.
- If atclk is not NULL: the driver requires atclk optional.
> Probably a 'which all clocks' flag based approach might been better ?
> But I guess this proposal will create less code churn.
So far, CoreSight driver has a fixed requirement for clocks.
- APB clock (pclk): it is mandatory. It can be either controlled by
AMBA bus driver or CoreSight driver.
- atclk: It is not required (CTCU) or it is optional.
Given the pattern is fixed, I don't think an extra flag would be helpful
at here. But I understand the code is not very strightforward, I will
add comments for easier understanding.
> > + *atclk = devm_clk_get_optional_enabled(dev, "atclk");
> > + if (IS_ERR(*atclk))
> > + return PTR_ERR(*atclk);
> > + }
>
> atclk when requested - either will have a valid clock or an error
> pointer but never a NULL pointer unlike the pclk clock ?
As mentioned, atclk can be a NULL pointer - it is optional and may be
absent in the device tree binding. This is why we use the optional
variant of the clock API to initialize it. If it returns a NULL
pointer, it is tolerated by IS_ERR(*atclk), and this is considered a
successful case.
Thanks,
Leo
^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2025-06-24 10:11 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-09 16:00 [PATCH v3 0/9] coresight: Fix and improve clock usage Leo Yan
2025-06-09 16:00 ` [PATCH v3 1/9] coresight: tmc: Support atclk Leo Yan
2025-06-09 16:00 ` [PATCH v3 2/9] coresight: catu: " Leo Yan
2025-06-09 16:00 ` [PATCH v3 3/9] coresight: etm4x: " Leo Yan
2025-06-09 16:00 ` [PATCH v3 4/9] coresight: Appropriately disable programming clocks Leo Yan
2025-06-09 16:11 ` Suzuki K Poulose
2025-06-09 16:38 ` Leo Yan
2025-06-24 4:23 ` Anshuman Khandual
2025-06-24 4:37 ` Anshuman Khandual
2025-06-09 16:00 ` [PATCH v3 5/9] coresight: Appropriately disable trace bus clocks Leo Yan
[not found] ` <89f9fede-3a0f-4ed6-a42d-43827f7a4fca@arm.com>
2025-06-09 16:43 ` Leo Yan
2025-06-09 16:00 ` [PATCH v3 6/9] coresight: Avoid enable programming clock duplicately Leo Yan
2025-06-09 16:58 ` Suzuki K Poulose
2025-06-09 17:14 ` Leo Yan
2025-06-10 10:39 ` Anshuman Khandual
2025-06-10 12:03 ` Leo Yan
2025-06-24 4:43 ` Anshuman Khandual
2025-06-24 5:11 ` Anshuman Khandual
2025-06-09 16:00 ` [PATCH v3 7/9] coresight: Consolidate clock enabling Leo Yan
2025-06-24 5:44 ` Anshuman Khandual
2025-06-24 10:08 ` Leo Yan
2025-06-09 16:00 ` [PATCH v3 8/9] coresight: Make clock sequence consistent Leo Yan
2025-06-09 16:00 ` [PATCH v3 9/9] coresight: Refactor runtime PM Leo Yan
2025-06-10 10:07 ` Anshuman Khandual
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).