aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/perf/arm_smmuv3_pmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/perf/arm_smmuv3_pmu.c')
-rw-r--r--drivers/perf/arm_smmuv3_pmu.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
index da71c741cb46..f3028f0d5f52 100644
--- a/drivers/perf/arm_smmuv3_pmu.c
+++ b/drivers/perf/arm_smmuv3_pmu.c
@@ -36,6 +36,7 @@
#include <linux/acpi.h>
#include <linux/acpi_iort.h>
+#include <linux/of.h>
#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/cpuhotplug.h>
@@ -280,8 +281,13 @@ static int smmu_pmu_apply_event_filter(struct smmu_pmu *smmu_pmu,
/* Requested settings same as current global settings*/
if (span == smmu_pmu->global_filter_span &&
- sid == smmu_pmu->global_filter_sid)
+ sid == smmu_pmu->global_filter_sid) {
+ if (idx == 0)
+ smmu_pmu_set_event_filter(event, idx, span, sid);
+ else
+ smmu_pmu_set_event_filter(event, idx, 0, 0);
return 0;
+ }
if (!bitmap_empty(smmu_pmu->used_counters, num_ctrs))
return -EAGAIN;
@@ -715,6 +721,7 @@ static int smmu_pmu_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, smmu_pmu);
smmu_pmu->pmu = (struct pmu) {
+ .module = THIS_MODULE,
.task_ctx_nr = perf_invalid_context,
.pmu_enable = smmu_pmu_enable,
.pmu_disable = smmu_pmu_disable,
@@ -745,7 +752,7 @@ static int smmu_pmu_probe(struct platform_device *pdev)
smmu_pmu->reloc_base = smmu_pmu->reg_base;
}
- irq = platform_get_irq(pdev, 0);
+ irq = platform_get_irq_optional(pdev, 0);
if (irq > 0)
smmu_pmu->irq = irq;
@@ -788,7 +795,7 @@ static int smmu_pmu_probe(struct platform_device *pdev)
if (err) {
dev_err(dev, "Error %d registering hotplug, PMU @%pa\n",
err, &res_0->start);
- goto out_cpuhp_err;
+ goto out_clear_affinity;
}
err = perf_pmu_register(&smmu_pmu->pmu, name, -1);
@@ -807,8 +814,8 @@ static int smmu_pmu_probe(struct platform_device *pdev)
out_unregister:
cpuhp_state_remove_instance_nocalls(cpuhp_state_num, &smmu_pmu->node);
-out_cpuhp_err:
- put_cpu();
+out_clear_affinity:
+ irq_set_affinity_hint(smmu_pmu->irq, NULL);
return err;
}
@@ -818,6 +825,7 @@ static int smmu_pmu_remove(struct platform_device *pdev)
perf_pmu_unregister(&smmu_pmu->pmu);
cpuhp_state_remove_instance_nocalls(cpuhp_state_num, &smmu_pmu->node);
+ irq_set_affinity_hint(smmu_pmu->irq, NULL);
return 0;
}
@@ -829,9 +837,17 @@ static void smmu_pmu_shutdown(struct platform_device *pdev)
smmu_pmu_disable(&smmu_pmu->pmu);
}
+static const struct of_device_id smmu_pmu_of_match[] = {
+ { .compatible = "arm,smmu-pmu-v3", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, smmu_pmu_of_match);
+
static struct platform_driver smmu_pmu_driver = {
.driver = {
.name = "arm-smmu-v3-pmcg",
+ .of_match_table = of_match_ptr(smmu_pmu_of_match),
+ .suppress_bind_attrs = true,
},
.probe = smmu_pmu_probe,
.remove = smmu_pmu_remove,