Skip to content

Commit 5394396

Browse files
rmurphy-armwilldeacon
authored andcommitted
perf/arm-cmn: Stop claiming entire iomem region
So far, the PMU has been the only thing of interest in the vast mass of CMN registers, so we've gotten away with simply claiming the entire iomem region. However, now that we can support other features like MPAM controllers for the system caches, the PMU driver needs to stop being selfish and learn to share. Similarly to arm-ni, requesting just the DTC node(s) should suffice for staking our exclusive claim to the PMU features, as requesting hundreds of tiny regions for all the individual pmu_event_sel registers is definitely not worth the considerable bother. As a consequence, we can also streamline the annoying CMN-600 special cases even more. The ACPI binding has in fact always specified a strict order for all resources, so we can reasonably drop the ancient pretence of swapping base and cfg, which IIRC was more just a moment of doubt on my part than anything else. Cc: James Morse <james.morse@arm.com> Signed-off-by: Robin Murphy <robin.murphy@arm.com> Tested-by: Ben Horgan <ben.horgan@arm.com> Reviewed-by: Ilkka Koskinen <ilkka@os.amperecomputing.com> Signed-off-by: Will Deacon <will@kernel.org>
1 parent 15ed3fa commit 5394396

1 file changed

Lines changed: 30 additions & 38 deletions

File tree

drivers/perf/arm-cmn.c

Lines changed: 30 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2132,13 +2132,22 @@ static void arm_cmn_init_dtm(struct arm_cmn_dtm *dtm, struct arm_cmn_node *xp, i
21322132
static int arm_cmn_init_dtc(struct arm_cmn *cmn, struct arm_cmn_node *dn, int idx)
21332133
{
21342134
struct arm_cmn_dtc *dtc = cmn->dtc + idx;
2135+
const struct resource *cfg;
2136+
resource_size_t base, size;
21352137

21362138
dtc->pmu_base = dn->pmu_base;
21372139
dtc->base = dtc->pmu_base - arm_cmn_pmu_offset(cmn, dn);
21382140
dtc->irq = platform_get_irq(to_platform_device(cmn->dev), idx);
21392141
if (dtc->irq < 0)
21402142
return dtc->irq;
21412143

2144+
cfg = platform_get_resource(to_platform_device(cmn->dev), IORESOURCE_MEM, 0);
2145+
base = dtc->base - cmn->base + cfg->start;
2146+
size = cmn->part == PART_CMN600 ? SZ_16K : SZ_64K;
2147+
if (!devm_request_mem_region(cmn->dev, base, size, dev_name(cmn->dev)))
2148+
return dev_err_probe(cmn->dev, -EBUSY,
2149+
"Failed to request DTC region 0x%llx\n", base);
2150+
21422151
writel_relaxed(CMN_DT_DTC_CTL_DT_EN, dtc->base + CMN_DT_DTC_CTL);
21432152
writel_relaxed(CMN_DT_PMCR_PMU_EN | CMN_DT_PMCR_OVFL_INTR_EN, CMN_DT_PMCR(dtc));
21442153
writeq_relaxed(0, CMN_DT_PMCCNTR(dtc));
@@ -2525,43 +2534,26 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
25252534
return 0;
25262535
}
25272536

2528-
static int arm_cmn600_acpi_probe(struct platform_device *pdev, struct arm_cmn *cmn)
2537+
static int arm_cmn_get_root(struct arm_cmn *cmn, const struct resource *cfg)
25292538
{
2530-
struct resource *cfg, *root;
2531-
2532-
cfg = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2533-
if (!cfg)
2534-
return -EINVAL;
2535-
2536-
root = platform_get_resource(pdev, IORESOURCE_MEM, 1);
2537-
if (!root)
2538-
return -EINVAL;
2539-
2540-
if (!resource_contains(cfg, root))
2541-
swap(cfg, root);
2542-
/*
2543-
* Note that devm_ioremap_resource() is dumb and won't let the platform
2544-
* device claim cfg when the ACPI companion device has already claimed
2545-
* root within it. But since they *are* already both claimed in the
2546-
* appropriate name, we don't really need to do it again here anyway.
2547-
*/
2548-
cmn->base = devm_ioremap(cmn->dev, cfg->start, resource_size(cfg));
2549-
if (!cmn->base)
2550-
return -ENOMEM;
2539+
const struct device_node *np = cmn->dev->of_node;
2540+
const struct resource *root;
2541+
u32 rootnode;
25512542

2552-
return root->start - cfg->start;
2553-
}
2543+
if (cmn->part != PART_CMN600)
2544+
return 0;
25542545

2555-
static int arm_cmn600_of_probe(struct device_node *np)
2556-
{
2557-
u32 rootnode;
2546+
if (np)
2547+
return of_property_read_u32(np, "arm,root-node", &rootnode) ?: rootnode;
25582548

2559-
return of_property_read_u32(np, "arm,root-node", &rootnode) ?: rootnode;
2549+
root = platform_get_resource(to_platform_device(cmn->dev), IORESOURCE_MEM, 1);
2550+
return root ? root->start - cfg->start : -EINVAL;
25602551
}
25612552

25622553
static int arm_cmn_probe(struct platform_device *pdev)
25632554
{
25642555
struct arm_cmn *cmn;
2556+
const struct resource *cfg;
25652557
const char *name;
25662558
static atomic_t id;
25672559
int err, rootnode, this_id;
@@ -2575,16 +2567,16 @@ static int arm_cmn_probe(struct platform_device *pdev)
25752567
cmn->cpu = cpumask_local_spread(0, dev_to_node(cmn->dev));
25762568
platform_set_drvdata(pdev, cmn);
25772569

2578-
if (cmn->part == PART_CMN600 && has_acpi_companion(cmn->dev)) {
2579-
rootnode = arm_cmn600_acpi_probe(pdev, cmn);
2580-
} else {
2581-
rootnode = 0;
2582-
cmn->base = devm_platform_ioremap_resource(pdev, 0);
2583-
if (IS_ERR(cmn->base))
2584-
return PTR_ERR(cmn->base);
2585-
if (cmn->part == PART_CMN600)
2586-
rootnode = arm_cmn600_of_probe(pdev->dev.of_node);
2587-
}
2570+
cfg = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2571+
if (!cfg)
2572+
return -EINVAL;
2573+
2574+
/* Map the whole region now, claim the DTCs once we've found them */
2575+
cmn->base = devm_ioremap(cmn->dev, cfg->start, resource_size(cfg));
2576+
if (IS_ERR(cmn->base))
2577+
return PTR_ERR(cmn->base);
2578+
2579+
rootnode = arm_cmn_get_root(cmn, cfg);
25882580
if (rootnode < 0)
25892581
return rootnode;
25902582

0 commit comments

Comments
 (0)