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,
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;
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;
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;
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; }
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))
} return ret; }clk_put(drvdata->pclk);
@@ -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))
return ret; }clk_disable_unprepare(drvdata->pclk);
@@ -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))
return ret; }clk_disable_unprepare(drvdata->pclk);
@@ -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;
dev_set_drvdata(dev, drvdata);return PTR_ERR(drvdata->pclk);
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;
dev_set_drvdata(dev, drvdata);return PTR_ERR(drvdata->pclk);
/* 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
*/ static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev) { struct clk *pclk;
- NULL - clock is not found
- ERROR - Clock is found but failed to enable
- 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; }
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
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))
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 ?
Cheers Suzuki
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))
drvdata->base = base; desc.groups = coresight_funnel_groups; desc.access = CSDEV_ACCESS_IOMEM(base);return PTR_ERR(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))
drvdata->base = base; desc.groups = replicator_groups; desc.access = CSDEV_ACCESS_IOMEM(base);return PTR_ERR(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))
dev->platform_data = pdata;return PTR_ERR(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))
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
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; }
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
*/ static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev) {
- NULL - Clock is not needed as it is managed by the AMBA bus driver
- ERROR - Clock is found but failed to enable
- 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; }
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; }
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; }
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
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 */
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
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
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))
return 0;clk_disable_unprepare(drvdata->pclk);
} 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))
return 0;clk_disable_unprepare(drvdata->pclk);
} 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))
return 0;clk_disable_unprepare(drvdata->pclk);
} 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