[PATCH 1/2] perf/arm-cmn: don't claim resource during ioremap() for CMN700 with ACPI
From: Yin Fengwei
Date: Mon Feb 17 2025 - 02:48:24 EST
Currently, arm-cmn PMU driver assumes ACPI claim resource
for CMN600 + ACPI. But with CMN700 + ACPI, the device probe
failed because of resource claim failes when function
devm_platform_ioremap_resource(pdev, 0) is called:
[ 10.837300] arm-cmn ARMHC700:00: error -EBUSY: can't request region for resource [mem 0x40000000-0x4fffffff]
[ 10.847310] arm-cmn ARMHC700:00: probe with driver arm-cmn failed with error -16
[ 10.854726] arm-cmn ARMHC700:02: error -EBUSY: can't request region for resource [mem 0x40040000000-0x4004fffffff]
[ 10.865085] arm-cmn ARMHC700:02: probe with driver arm-cmn failed with error -16
Let all ACPI cases call devm_ioremap(cmn->dev, cfg) just
like current CMN600 does.
Signed-off-by: Yin Fengwei <fengwei_yin@xxxxxxxxxxxxxxxxx>
---
drivers/perf/arm-cmn.c | 28 +++++++++++++++++-----------
1 file changed, 17 insertions(+), 11 deletions(-)
diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
index ef959e66db7c..5993a46c5560 100644
--- a/drivers/perf/arm-cmn.c
+++ b/drivers/perf/arm-cmn.c
@@ -2510,20 +2510,26 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
return 0;
}
-static int arm_cmn600_acpi_probe(struct platform_device *pdev, struct arm_cmn *cmn)
+static int arm_acpi_probe(struct platform_device *pdev, struct arm_cmn *cmn)
{
- struct resource *cfg, *root;
+ struct resource *cfg, *root = NULL;
cfg = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!cfg)
return -EINVAL;
- root = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- if (!root)
- return -EINVAL;
+ if (cmn->part == PART_CMN600) {
+ /* Per "ACPI for Arm Components" Table 16, CMN600 has
+ * nested root node memory range.
+ */
+ root = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!root)
+ return -EINVAL;
+
+ if (!resource_contains(cfg, root))
+ swap(cfg, root);
+ }
- if (!resource_contains(cfg, root))
- swap(cfg, root);
/*
* Note that devm_ioremap_resource() is dumb and won't let the platform
* device claim cfg when the ACPI companion device has already claimed
@@ -2534,7 +2540,7 @@ static int arm_cmn600_acpi_probe(struct platform_device *pdev, struct arm_cmn *c
if (!cmn->base)
return -ENOMEM;
- return root->start - cfg->start;
+ return root ? (root->start - cfg->start) : 0;
}
static int arm_cmn600_of_probe(struct device_node *np)
@@ -2559,9 +2565,9 @@ static int arm_cmn_probe(struct platform_device *pdev)
cmn->part = (unsigned long)device_get_match_data(cmn->dev);
platform_set_drvdata(pdev, cmn);
- if (cmn->part == PART_CMN600 && has_acpi_companion(cmn->dev)) {
- rootnode = arm_cmn600_acpi_probe(pdev, cmn);
- } else {
+ if (has_acpi_companion(cmn->dev))
+ rootnode = arm_acpi_probe(pdev, cmn);
+ else {
rootnode = 0;
cmn->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(cmn->base))
--
2.43.5