diff options
-rw-r--r-- | arch/arm/include/asm/perf_event.h | 14 | ||||
-rw-r--r-- | arch/arm/kernel/perf_event.c | 39 |
2 files changed, 43 insertions, 10 deletions
diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h index 49e3049aba32..fa4b32625d37 100644 --- a/arch/arm/include/asm/perf_event.h +++ b/arch/arm/include/asm/perf_event.h | |||
@@ -28,4 +28,18 @@ set_perf_event_pending(void) | |||
28 | * same indexes here for consistency. */ | 28 | * same indexes here for consistency. */ |
29 | #define PERF_EVENT_INDEX_OFFSET 1 | 29 | #define PERF_EVENT_INDEX_OFFSET 1 |
30 | 30 | ||
31 | /* ARM perf PMU IDs for use by internal perf clients. */ | ||
32 | enum arm_perf_pmu_ids { | ||
33 | ARM_PERF_PMU_ID_XSCALE1 = 0, | ||
34 | ARM_PERF_PMU_ID_XSCALE2, | ||
35 | ARM_PERF_PMU_ID_V6, | ||
36 | ARM_PERF_PMU_ID_V6MP, | ||
37 | ARM_PERF_PMU_ID_CA8, | ||
38 | ARM_PERF_PMU_ID_CA9, | ||
39 | ARM_NUM_PMU_IDS, | ||
40 | }; | ||
41 | |||
42 | extern enum arm_perf_pmu_ids | ||
43 | armpmu_get_pmu_id(void); | ||
44 | |||
31 | #endif /* __ARM_PERF_EVENT_H__ */ | 45 | #endif /* __ARM_PERF_EVENT_H__ */ |
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 89a77fcb13e3..10a0bcdf2158 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/module.h> | ||
19 | #include <linux/perf_event.h> | 20 | #include <linux/perf_event.h> |
20 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
21 | #include <linux/spinlock.h> | 22 | #include <linux/spinlock.h> |
@@ -68,8 +69,18 @@ struct cpu_hw_events { | |||
68 | }; | 69 | }; |
69 | DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events); | 70 | DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events); |
70 | 71 | ||
72 | /* PMU names. */ | ||
73 | static const char *arm_pmu_names[] = { | ||
74 | [ARM_PERF_PMU_ID_XSCALE1] = "xscale1", | ||
75 | [ARM_PERF_PMU_ID_XSCALE2] = "xscale2", | ||
76 | [ARM_PERF_PMU_ID_V6] = "v6", | ||
77 | [ARM_PERF_PMU_ID_V6MP] = "v6mpcore", | ||
78 | [ARM_PERF_PMU_ID_CA8] = "ARMv7 Cortex-A8", | ||
79 | [ARM_PERF_PMU_ID_CA9] = "ARMv7 Cortex-A9", | ||
80 | }; | ||
81 | |||
71 | struct arm_pmu { | 82 | struct arm_pmu { |
72 | char *name; | 83 | enum arm_perf_pmu_ids id; |
73 | irqreturn_t (*handle_irq)(int irq_num, void *dev); | 84 | irqreturn_t (*handle_irq)(int irq_num, void *dev); |
74 | void (*enable)(struct hw_perf_event *evt, int idx); | 85 | void (*enable)(struct hw_perf_event *evt, int idx); |
75 | void (*disable)(struct hw_perf_event *evt, int idx); | 86 | void (*disable)(struct hw_perf_event *evt, int idx); |
@@ -88,6 +99,18 @@ struct arm_pmu { | |||
88 | /* Set at runtime when we know what CPU type we are. */ | 99 | /* Set at runtime when we know what CPU type we are. */ |
89 | static const struct arm_pmu *armpmu; | 100 | static const struct arm_pmu *armpmu; |
90 | 101 | ||
102 | enum arm_perf_pmu_ids | ||
103 | armpmu_get_pmu_id(void) | ||
104 | { | ||
105 | int id = -ENODEV; | ||
106 | |||
107 | if (armpmu != NULL) | ||
108 | id = armpmu->id; | ||
109 | |||
110 | return id; | ||
111 | } | ||
112 | EXPORT_SYMBOL_GPL(armpmu_get_pmu_id); | ||
113 | |||
91 | #define HW_OP_UNSUPPORTED 0xFFFF | 114 | #define HW_OP_UNSUPPORTED 0xFFFF |
92 | 115 | ||
93 | #define C(_x) \ | 116 | #define C(_x) \ |
@@ -1154,7 +1177,7 @@ armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc, | |||
1154 | } | 1177 | } |
1155 | 1178 | ||
1156 | static const struct arm_pmu armv6pmu = { | 1179 | static const struct arm_pmu armv6pmu = { |
1157 | .name = "v6", | 1180 | .id = ARM_PERF_PMU_ID_V6, |
1158 | .handle_irq = armv6pmu_handle_irq, | 1181 | .handle_irq = armv6pmu_handle_irq, |
1159 | .enable = armv6pmu_enable_event, | 1182 | .enable = armv6pmu_enable_event, |
1160 | .disable = armv6pmu_disable_event, | 1183 | .disable = armv6pmu_disable_event, |
@@ -1177,7 +1200,7 @@ static const struct arm_pmu armv6pmu = { | |||
1177 | * reset the period and enable the interrupt reporting. | 1200 | * reset the period and enable the interrupt reporting. |
1178 | */ | 1201 | */ |
1179 | static const struct arm_pmu armv6mpcore_pmu = { | 1202 | static const struct arm_pmu armv6mpcore_pmu = { |
1180 | .name = "v6mpcore", | 1203 | .id = ARM_PERF_PMU_ID_V6MP, |
1181 | .handle_irq = armv6pmu_handle_irq, | 1204 | .handle_irq = armv6pmu_handle_irq, |
1182 | .enable = armv6pmu_enable_event, | 1205 | .enable = armv6pmu_enable_event, |
1183 | .disable = armv6mpcore_pmu_disable_event, | 1206 | .disable = armv6mpcore_pmu_disable_event, |
@@ -1207,10 +1230,6 @@ static const struct arm_pmu armv6mpcore_pmu = { | |||
1207 | * counter and all 4 performance counters together can be reset separately. | 1230 | * counter and all 4 performance counters together can be reset separately. |
1208 | */ | 1231 | */ |
1209 | 1232 | ||
1210 | #define ARMV7_PMU_CORTEX_A8_NAME "ARMv7 Cortex-A8" | ||
1211 | |||
1212 | #define ARMV7_PMU_CORTEX_A9_NAME "ARMv7 Cortex-A9" | ||
1213 | |||
1214 | /* Common ARMv7 event types */ | 1233 | /* Common ARMv7 event types */ |
1215 | enum armv7_perf_types { | 1234 | enum armv7_perf_types { |
1216 | ARMV7_PERFCTR_PMNC_SW_INCR = 0x00, | 1235 | ARMV7_PERFCTR_PMNC_SW_INCR = 0x00, |
@@ -2115,7 +2134,7 @@ init_hw_perf_events(void) | |||
2115 | perf_max_events = armv6mpcore_pmu.num_events; | 2134 | perf_max_events = armv6mpcore_pmu.num_events; |
2116 | break; | 2135 | break; |
2117 | case 0xC080: /* Cortex-A8 */ | 2136 | case 0xC080: /* Cortex-A8 */ |
2118 | armv7pmu.name = ARMV7_PMU_CORTEX_A8_NAME; | 2137 | armv7pmu.id = ARM_PERF_PMU_ID_CA8; |
2119 | memcpy(armpmu_perf_cache_map, armv7_a8_perf_cache_map, | 2138 | memcpy(armpmu_perf_cache_map, armv7_a8_perf_cache_map, |
2120 | sizeof(armv7_a8_perf_cache_map)); | 2139 | sizeof(armv7_a8_perf_cache_map)); |
2121 | armv7pmu.event_map = armv7_a8_pmu_event_map; | 2140 | armv7pmu.event_map = armv7_a8_pmu_event_map; |
@@ -2127,7 +2146,7 @@ init_hw_perf_events(void) | |||
2127 | perf_max_events = armv7pmu.num_events; | 2146 | perf_max_events = armv7pmu.num_events; |
2128 | break; | 2147 | break; |
2129 | case 0xC090: /* Cortex-A9 */ | 2148 | case 0xC090: /* Cortex-A9 */ |
2130 | armv7pmu.name = ARMV7_PMU_CORTEX_A9_NAME; | 2149 | armv7pmu.id = ARM_PERF_PMU_ID_CA9; |
2131 | memcpy(armpmu_perf_cache_map, armv7_a9_perf_cache_map, | 2150 | memcpy(armpmu_perf_cache_map, armv7_a9_perf_cache_map, |
2132 | sizeof(armv7_a9_perf_cache_map)); | 2151 | sizeof(armv7_a9_perf_cache_map)); |
2133 | armv7pmu.event_map = armv7_a9_pmu_event_map; | 2152 | armv7pmu.event_map = armv7_a9_pmu_event_map; |
@@ -2146,7 +2165,7 @@ init_hw_perf_events(void) | |||
2146 | 2165 | ||
2147 | if (armpmu) | 2166 | if (armpmu) |
2148 | pr_info("enabled with %s PMU driver, %d counters available\n", | 2167 | pr_info("enabled with %s PMU driver, %d counters available\n", |
2149 | armpmu->name, armpmu->num_events); | 2168 | arm_pmu_names[armpmu->id], armpmu->num_events); |
2150 | 2169 | ||
2151 | return 0; | 2170 | return 0; |
2152 | } | 2171 | } |