perf pmu: Remove duplication around EVENT_SOURCE_DEVICE_PATH
[platform/kernel/linux-rpi.git] / tools / perf / arch / arm64 / util / pmu.c
1 // SPDX-License-Identifier: GPL-2.0
2
3 #include <internal/cpumap.h>
4 #include "../../../util/cpumap.h"
5 #include "../../../util/pmu.h"
6 #include <api/fs/fs.h>
7 #include <math.h>
8
9 static struct perf_pmu *pmu__find_core_pmu(void)
10 {
11         struct perf_pmu *pmu = NULL;
12
13         while ((pmu = perf_pmu__scan(pmu))) {
14                 if (!is_pmu_core(pmu->name))
15                         continue;
16
17                 /*
18                  * The cpumap should cover all CPUs. Otherwise, some CPUs may
19                  * not support some events or have different event IDs.
20                  */
21                 if (pmu->cpus->nr != cpu__max_cpu().cpu)
22                         return NULL;
23
24                 return pmu;
25         }
26
27         return NULL;
28 }
29
30 const struct pmu_events_table *pmu_events_table__find(void)
31 {
32         struct perf_pmu *pmu = pmu__find_core_pmu();
33
34         if (pmu)
35                 return perf_pmu__find_table(pmu);
36
37         return NULL;
38 }
39
40 double perf_pmu__cpu_slots_per_cycle(void)
41 {
42         char path[PATH_MAX];
43         unsigned long long slots = 0;
44         struct perf_pmu *pmu = pmu__find_core_pmu();
45
46         if (pmu) {
47                 perf_pmu__pathname_scnprintf(path, sizeof(path),
48                                              pmu->name, "caps/slots");
49                 /*
50                  * The value of slots is not greater than 32 bits, but sysfs__read_int
51                  * can't read value with 0x prefix, so use sysfs__read_ull instead.
52                  */
53                 sysfs__read_ull(path, &slots);
54         }
55
56         return slots ? (double)slots : NAN;
57 }