Skip to content
This repository has been archived by the owner on Jul 16, 2024. It is now read-only.

Commit

Permalink
perf/smmuv3: Allow sharing MMIO registers with the SMMU driver
Browse files Browse the repository at this point in the history
Some Arm SMMUv3 implementations, for example Arm CoreLink MMU-600, embed
the PMCG registers into the SMMU MMIO regions. It currently causes probe
failure because the PMU and SMMU drivers request overlapping resources.

Avoid the conflict by calling devm_ioremap() directly from the PMU
driver. We loose some sanity-checking of the memory map provided by
firmware, which doesn't seem catastrophic.

Backport from: https://lore.kernel.org/linux-arm-kernel/[email protected]/
Signed-off-by: Jean-Philippe Brucker <[email protected]>
Signed-off-by: Tuan Phan <[email protected]>

Signed-off-by: Tuan Phan <[email protected]>
  • Loading branch information
tphan-ampere committed Jun 30, 2020
1 parent 43046fc commit 1164351
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 7 deletions.
2 changes: 1 addition & 1 deletion drivers/iommu/arm-smmu-v3.c
Original file line number Diff line number Diff line change
Expand Up @@ -2854,7 +2854,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
}
ioaddr = res->start;

smmu->base = devm_ioremap_resource(dev, res);
smmu->base = devm_ioremap(dev, res->start, resource_size(res));
if (IS_ERR(smmu->base))
return PTR_ERR(smmu->base);

Expand Down
25 changes: 19 additions & 6 deletions drivers/perf/arm_smmuv3_pmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -723,19 +723,32 @@ static int smmu_pmu_probe(struct platform_device *pdev)
.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
};

/*
* If the PMCG registers are embedded into the SMMU regions, the
* resources have to be shared with the SMMU driver. Use ioremap()
* rather than ioremap_resource() to avoid conflicts.
*/
res_0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
smmu_pmu->reg_base = devm_ioremap_resource(dev, res_0);
if (IS_ERR(smmu_pmu->reg_base))
return PTR_ERR(smmu_pmu->reg_base);
if (!res_0)
return -ENXIO;

smmu_pmu->reg_base = devm_ioremap(dev, res_0->start,
resource_size(res_0));
if (!smmu_pmu->reg_base)
return -ENOMEM;

cfgr = readl_relaxed(smmu_pmu->reg_base + SMMU_PMCG_CFGR);

/* Determine if page 1 is present */
if (cfgr & SMMU_PMCG_CFGR_RELOC_CTRS) {
res_1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
smmu_pmu->reloc_base = devm_ioremap_resource(dev, res_1);
if (IS_ERR(smmu_pmu->reloc_base))
return PTR_ERR(smmu_pmu->reloc_base);
if (!res_1)
return -ENXIO;

smmu_pmu->reloc_base = devm_ioremap(dev, res_1->start,
resource_size(res_1));
if (!smmu_pmu->reloc_base)
return -ENOMEM;
} else {
smmu_pmu->reloc_base = smmu_pmu->reg_base;
}
Expand Down

0 comments on commit 1164351

Please sign in to comment.