Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

coresight: Consolidate clock enabling

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.

CoreSight drivers are refined so that clocks are initialized in one go.
For this purpose, this commit 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.
- For ACPI devices, clocks are controlled by firmware, directly bail
out.
- Skip enabling pclk for an AMBA device.
- 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.

Suggested-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com>
Tested-by: James Clark <james.clark@linaro.org>
Signed-off-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Link: https://lore.kernel.org/r/20250731-arm_cs_fix_clock_v4-v6-7-1dfe10bb3f6f@arm.com

authored by

Leo Yan and committed by
Suzuki K Poulose
fbe7514a d091c631

+83 -83
+3 -7
drivers/hwtracing/coresight/coresight-catu.c
··· 520 520 struct coresight_platform_data *pdata = NULL; 521 521 void __iomem *base; 522 522 523 - drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk"); 524 - if (IS_ERR(drvdata->atclk)) 525 - return PTR_ERR(drvdata->atclk); 523 + ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk); 524 + if (ret) 525 + return ret; 526 526 527 527 catu_desc.name = coresight_alloc_device_name(&catu_devs, dev); 528 528 if (!catu_desc.name) ··· 633 633 drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); 634 634 if (!drvdata) 635 635 return -ENOMEM; 636 - 637 - drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev); 638 - if (IS_ERR(drvdata->pclk)) 639 - return PTR_ERR(drvdata->pclk); 640 636 641 637 pm_runtime_get_noresume(&pdev->dev); 642 638 pm_runtime_set_active(&pdev->dev);
+48
drivers/hwtracing/coresight/coresight-core.c
··· 3 3 * Copyright (c) 2012, The Linux Foundation. All rights reserved. 4 4 */ 5 5 6 + #include <linux/acpi.h> 6 7 #include <linux/bitfield.h> 7 8 #include <linux/build_bug.h> 8 9 #include <linux/kernel.h> ··· 1700 1699 return trace_id; 1701 1700 } 1702 1701 EXPORT_SYMBOL_GPL(coresight_etm_get_trace_id); 1702 + 1703 + /* 1704 + * Attempt to find and enable programming clock (pclk) and trace clock (atclk) 1705 + * for the given device. 1706 + * 1707 + * For ACPI devices, clocks are controlled by firmware, so bail out early in 1708 + * this case. Also, skip enabling pclk if the clock is managed by the AMBA 1709 + * bus driver instead. 1710 + * 1711 + * atclk is an optional clock, it will be only enabled when it is existed. 1712 + * Otherwise, a NULL pointer will be returned to caller. 1713 + * 1714 + * Returns: '0' on Success; Error code otherwise. 1715 + */ 1716 + int coresight_get_enable_clocks(struct device *dev, struct clk **pclk, 1717 + struct clk **atclk) 1718 + { 1719 + WARN_ON(!pclk); 1720 + 1721 + if (has_acpi_companion(dev)) 1722 + return 0; 1723 + 1724 + if (!dev_is_amba(dev)) { 1725 + /* 1726 + * "apb_pclk" is the default clock name for an Arm Primecell 1727 + * peripheral, while "apb" is used only by the CTCU driver. 1728 + * 1729 + * For easier maintenance, CoreSight drivers should use 1730 + * "apb_pclk" as the programming clock name. 1731 + */ 1732 + *pclk = devm_clk_get_optional_enabled(dev, "apb_pclk"); 1733 + if (!*pclk) 1734 + *pclk = devm_clk_get_optional_enabled(dev, "apb"); 1735 + if (IS_ERR(*pclk)) 1736 + return PTR_ERR(*pclk); 1737 + } 1738 + 1739 + /* Initialization of atclk is skipped if it is a NULL pointer. */ 1740 + if (atclk) { 1741 + *atclk = devm_clk_get_optional_enabled(dev, "atclk"); 1742 + if (IS_ERR(*atclk)) 1743 + return PTR_ERR(*atclk); 1744 + } 1745 + 1746 + return 0; 1747 + } 1748 + EXPORT_SYMBOL_GPL(coresight_get_enable_clocks); 1703 1749 1704 1750 MODULE_LICENSE("GPL v2"); 1705 1751 MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
+4 -4
drivers/hwtracing/coresight/coresight-cpu-debug.c
··· 566 566 void __iomem *base; 567 567 int ret; 568 568 569 + ret = coresight_get_enable_clocks(dev, &drvdata->pclk, NULL); 570 + if (ret) 571 + return ret; 572 + 569 573 drvdata->cpu = coresight_get_cpu(dev); 570 574 if (drvdata->cpu < 0) 571 575 return drvdata->cpu; ··· 700 696 drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); 701 697 if (!drvdata) 702 698 return -ENOMEM; 703 - 704 - drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev); 705 - if (IS_ERR(drvdata->pclk)) 706 - return PTR_ERR(drvdata->pclk); 707 699 708 700 dev_set_drvdata(&pdev->dev, drvdata); 709 701 pm_runtime_get_noresume(&pdev->dev);
+4 -4
drivers/hwtracing/coresight/coresight-ctcu-core.c
··· 188 188 const struct ctcu_config *cfgs; 189 189 struct ctcu_drvdata *drvdata; 190 190 void __iomem *base; 191 - int i; 191 + int i, ret; 192 192 193 193 desc.name = coresight_alloc_device_name(&ctcu_devs, dev); 194 194 if (!desc.name) ··· 207 207 if (IS_ERR(base)) 208 208 return PTR_ERR(base); 209 209 210 - drvdata->apb_clk = coresight_get_enable_apb_pclk(dev); 211 - if (IS_ERR(drvdata->apb_clk)) 212 - return PTR_ERR(drvdata->apb_clk); 210 + ret = coresight_get_enable_clocks(dev, &drvdata->apb_clk, NULL); 211 + if (ret) 212 + return ret; 213 213 214 214 cfgs = of_device_get_match_data(dev); 215 215 if (cfgs) {
+4 -7
drivers/hwtracing/coresight/coresight-etm4x-core.c
··· 2217 2217 struct csdev_access access = { 0 }; 2218 2218 struct etm4_init_arg init_arg = { 0 }; 2219 2219 struct etm4_init_arg *delayed; 2220 + int ret; 2220 2221 2221 2222 if (WARN_ON(!drvdata)) 2222 2223 return -ENOMEM; 2223 2224 2224 - drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk"); 2225 - if (IS_ERR(drvdata->atclk)) 2226 - return PTR_ERR(drvdata->atclk); 2225 + ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk); 2226 + if (ret) 2227 + return ret; 2227 2228 2228 2229 if (pm_save_enable == PARAM_PM_SAVE_FIRMWARE) 2229 2230 pm_save_enable = coresight_loses_context_with_cpu(dev) ? ··· 2307 2306 drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); 2308 2307 if (!drvdata) 2309 2308 return -ENOMEM; 2310 - 2311 - drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev); 2312 - if (IS_ERR(drvdata->pclk)) 2313 - return PTR_ERR(drvdata->pclk); 2314 2309 2315 2310 if (res) { 2316 2311 drvdata->base = devm_ioremap_resource(&pdev->dev, res);
+4 -7
drivers/hwtracing/coresight/coresight-funnel.c
··· 217 217 struct coresight_platform_data *pdata = NULL; 218 218 struct funnel_drvdata *drvdata; 219 219 struct coresight_desc desc = { 0 }; 220 + int ret; 220 221 221 222 if (is_of_node(dev_fwnode(dev)) && 222 223 of_device_is_compatible(dev->of_node, "arm,coresight-funnel")) ··· 231 230 if (!drvdata) 232 231 return -ENOMEM; 233 232 234 - drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk"); 235 - if (IS_ERR(drvdata->atclk)) 236 - return PTR_ERR(drvdata->atclk); 237 - 238 - drvdata->pclk = coresight_get_enable_apb_pclk(dev); 239 - if (IS_ERR(drvdata->pclk)) 240 - return PTR_ERR(drvdata->pclk); 233 + ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk); 234 + if (ret) 235 + return ret; 241 236 242 237 /* 243 238 * Map the device base for dynamic-funnel, which has been
+4 -7
drivers/hwtracing/coresight/coresight-replicator.c
··· 223 223 struct replicator_drvdata *drvdata; 224 224 struct coresight_desc desc = { 0 }; 225 225 void __iomem *base; 226 + int ret; 226 227 227 228 if (is_of_node(dev_fwnode(dev)) && 228 229 of_device_is_compatible(dev->of_node, "arm,coresight-replicator")) ··· 238 237 if (!drvdata) 239 238 return -ENOMEM; 240 239 241 - drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk"); 242 - if (IS_ERR(drvdata->atclk)) 243 - return PTR_ERR(drvdata->atclk); 244 - 245 - drvdata->pclk = coresight_get_enable_apb_pclk(dev); 246 - if (IS_ERR(drvdata->pclk)) 247 - return PTR_ERR(drvdata->pclk); 240 + ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk); 241 + if (ret) 242 + return ret; 248 243 249 244 /* 250 245 * Map the device base for dynamic-replicator, which has been
+3 -6
drivers/hwtracing/coresight/coresight-stm.c
··· 842 842 if (!drvdata) 843 843 return -ENOMEM; 844 844 845 - drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk"); 846 - if (IS_ERR(drvdata->atclk)) 847 - return PTR_ERR(drvdata->atclk); 845 + ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk); 846 + if (ret) 847 + return ret; 848 848 849 - drvdata->pclk = coresight_get_enable_apb_pclk(dev); 850 - if (IS_ERR(drvdata->pclk)) 851 - return PTR_ERR(drvdata->pclk); 852 849 dev_set_drvdata(dev, drvdata); 853 850 854 851 base = devm_ioremap_resource(dev, res);
+3 -7
drivers/hwtracing/coresight/coresight-tmc-core.c
··· 779 779 struct coresight_desc desc = { 0 }; 780 780 struct coresight_dev_list *dev_list = NULL; 781 781 782 - drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk"); 783 - if (IS_ERR(drvdata->atclk)) 784 - return PTR_ERR(drvdata->atclk); 782 + ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk); 783 + if (ret) 784 + return ret; 785 785 786 786 ret = -ENOMEM; 787 787 ··· 978 978 drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); 979 979 if (!drvdata) 980 980 return -ENOMEM; 981 - 982 - drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev); 983 - if (IS_ERR(drvdata->pclk)) 984 - return PTR_ERR(drvdata->pclk); 985 981 986 982 dev_set_drvdata(&pdev->dev, drvdata); 987 983 pm_runtime_get_noresume(&pdev->dev);
+4 -6
drivers/hwtracing/coresight/coresight-tpiu.c
··· 132 132 struct coresight_platform_data *pdata = NULL; 133 133 struct tpiu_drvdata *drvdata; 134 134 struct coresight_desc desc = { 0 }; 135 + int ret; 135 136 136 137 desc.name = coresight_alloc_device_name(&tpiu_devs, dev); 137 138 if (!desc.name) ··· 144 143 145 144 spin_lock_init(&drvdata->spinlock); 146 145 147 - drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk"); 148 - if (IS_ERR(drvdata->atclk)) 149 - return PTR_ERR(drvdata->atclk); 146 + ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk); 147 + if (ret) 148 + return ret; 150 149 151 - drvdata->pclk = coresight_get_enable_apb_pclk(dev); 152 - if (IS_ERR(drvdata->pclk)) 153 - return PTR_ERR(drvdata->pclk); 154 150 dev_set_drvdata(dev, drvdata); 155 151 156 152 /* Validity for the resource is already checked by the AMBA core */
+2 -28
include/linux/coresight.h
··· 6 6 #ifndef _LINUX_CORESIGHT_H 7 7 #define _LINUX_CORESIGHT_H 8 8 9 - #include <linux/acpi.h> 10 9 #include <linux/amba/bus.h> 11 10 #include <linux/clk.h> 12 11 #include <linux/device.h> ··· 474 475 return cid == CORESIGHT_CID; 475 476 } 476 477 477 - /* 478 - * Attempt to find and enable "APB clock" for the given device 479 - * 480 - * Returns: 481 - * 482 - * clk - Clock is found and enabled 483 - * NULL - Clock is controlled by firmware (ACPI device only) or when managed 484 - * by the AMBA bus driver instead 485 - * ERROR - Clock is found but failed to enable 486 - */ 487 - static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev) 488 - { 489 - struct clk *pclk = NULL; 490 - 491 - /* Firmware controls clocks for an ACPI device. */ 492 - if (has_acpi_companion(dev)) 493 - return NULL; 494 - 495 - if (!dev_is_amba(dev)) { 496 - pclk = devm_clk_get_optional_enabled(dev, "apb_pclk"); 497 - if (!pclk) 498 - pclk = devm_clk_get_optional_enabled(dev, "apb"); 499 - } 500 - 501 - return pclk; 502 - } 503 - 504 478 #define CORESIGHT_PIDRn(i) (0xFE0 + ((i) * 4)) 505 479 506 480 static inline u32 coresight_get_pid(struct csdev_access *csa) ··· 704 732 struct platform_driver *pdev_drv); 705 733 int coresight_etm_get_trace_id(struct coresight_device *csdev, enum cs_mode mode, 706 734 struct coresight_device *sink); 735 + int coresight_get_enable_clocks(struct device *dev, struct clk **pclk, 736 + struct clk **atclk); 707 737 #endif /* _LINUX_COREISGHT_H */