1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Driver for the Uncore PMUs in Fujitsu chips.
4 *
5 * See Documentation/admin-guide/perf/fujitsu_uncore_pmu.rst for more details.
6 *
7 * Copyright (c) 2025 Fujitsu. All rights reserved.
8 */
9
10 #include <linux/acpi.h>
11 #include <linux/bitfield.h>
12 #include <linux/bitops.h>
13 #include <linux/interrupt.h>
14 #include <linux/io.h>
15 #include <linux/list.h>
16 #include <linux/module.h>
17 #include <linux/perf_event.h>
18 #include <linux/platform_device.h>
19
20 /* Number of counters on each PMU */
21 #define MAC_NUM_COUNTERS 8
22 #define PCI_NUM_COUNTERS 8
23 /* Mask for the event type field within perf_event_attr.config and EVTYPE reg */
24 #define UNCORE_EVTYPE_MASK 0xFF
25
26 /* Perfmon registers */
27 #define PM_EVCNTR(__cntr) (0x000 + (__cntr) * 8)
28 #define PM_CNTCTL(__cntr) (0x100 + (__cntr) * 8)
29 #define PM_CNTCTL_RESET 0
30 #define PM_EVTYPE(__cntr) (0x200 + (__cntr) * 8)
31 #define PM_EVTYPE_EVSEL(__val) FIELD_GET(UNCORE_EVTYPE_MASK, __val)
32 #define PM_CR 0x400
33 #define PM_CR_RESET BIT(1)
34 #define PM_CR_ENABLE BIT(0)
35 #define PM_CNTENSET 0x410
36 #define PM_CNTENSET_IDX(__cntr) BIT(__cntr)
37 #define PM_CNTENCLR 0x418
38 #define PM_CNTENCLR_IDX(__cntr) BIT(__cntr)
39 #define PM_CNTENCLR_RESET 0xFF
40 #define PM_INTENSET 0x420
41 #define PM_INTENSET_IDX(__cntr) BIT(__cntr)
42 #define PM_INTENCLR 0x428
43 #define PM_INTENCLR_IDX(__cntr) BIT(__cntr)
44 #define PM_INTENCLR_RESET 0xFF
45 #define PM_OVSR 0x440
46 #define PM_OVSR_OVSRCLR_RESET 0xFF
47
48 enum fujitsu_uncore_pmu {
49 FUJITSU_UNCORE_PMU_MAC = 1,
50 FUJITSU_UNCORE_PMU_PCI = 2,
51 };
52
53 struct uncore_pmu {
54 int num_counters;
55 struct pmu pmu;
56 struct hlist_node node;
57 void __iomem *regs;
58 struct perf_event **events;
59 unsigned long *used_mask;
60 int cpu;
61 int irq;
62 struct device *dev;
63 };
64
65 #define to_uncore_pmu(p) (container_of(p, struct uncore_pmu, pmu))
66
67 static int uncore_pmu_cpuhp_state;
68
fujitsu_uncore_counter_start(struct perf_event * event)69 static void fujitsu_uncore_counter_start(struct perf_event *event)
70 {
71 struct uncore_pmu *uncorepmu = to_uncore_pmu(event->pmu);
72 int idx = event->hw.idx;
73
74 /* Initialize the hardware counter and reset prev_count*/
75 local64_set(&event->hw.prev_count, 0);
76 writeq_relaxed(0, uncorepmu->regs + PM_EVCNTR(idx));
77
78 /* Set the event type */
79 writeq_relaxed(PM_EVTYPE_EVSEL(event->attr.config), uncorepmu->regs + PM_EVTYPE(idx));
80
81 /* Enable interrupt generation by this counter */
82 writeq_relaxed(PM_INTENSET_IDX(idx), uncorepmu->regs + PM_INTENSET);
83
84 /* Finally, enable the counter */
85 writeq_relaxed(PM_CNTCTL_RESET, uncorepmu->regs + PM_CNTCTL(idx));
86 writeq_relaxed(PM_CNTENSET_IDX(idx), uncorepmu->regs + PM_CNTENSET);
87 }
88
fujitsu_uncore_counter_stop(struct perf_event * event)89 static void fujitsu_uncore_counter_stop(struct perf_event *event)
90 {
91 struct uncore_pmu *uncorepmu = to_uncore_pmu(event->pmu);
92 int idx = event->hw.idx;
93
94 /* Disable the counter */
95 writeq_relaxed(PM_CNTENCLR_IDX(idx), uncorepmu->regs + PM_CNTENCLR);
96
97 /* Disable interrupt generation by this counter */
98 writeq_relaxed(PM_INTENCLR_IDX(idx), uncorepmu->regs + PM_INTENCLR);
99 }
100
fujitsu_uncore_counter_update(struct perf_event * event)101 static void fujitsu_uncore_counter_update(struct perf_event *event)
102 {
103 struct uncore_pmu *uncorepmu = to_uncore_pmu(event->pmu);
104 int idx = event->hw.idx;
105 u64 prev, new;
106
107 do {
108 prev = local64_read(&event->hw.prev_count);
109 new = readq_relaxed(uncorepmu->regs + PM_EVCNTR(idx));
110 } while (local64_cmpxchg(&event->hw.prev_count, prev, new) != prev);
111
112 local64_add(new - prev, &event->count);
113 }
114
fujitsu_uncore_init(struct uncore_pmu * uncorepmu)115 static inline void fujitsu_uncore_init(struct uncore_pmu *uncorepmu)
116 {
117 int i;
118
119 writeq_relaxed(PM_CR_RESET, uncorepmu->regs + PM_CR);
120
121 writeq_relaxed(PM_CNTENCLR_RESET, uncorepmu->regs + PM_CNTENCLR);
122 writeq_relaxed(PM_INTENCLR_RESET, uncorepmu->regs + PM_INTENCLR);
123 writeq_relaxed(PM_OVSR_OVSRCLR_RESET, uncorepmu->regs + PM_OVSR);
124
125 for (i = 0; i < uncorepmu->num_counters; ++i) {
126 writeq_relaxed(PM_CNTCTL_RESET, uncorepmu->regs + PM_CNTCTL(i));
127 writeq_relaxed(PM_EVTYPE_EVSEL(0), uncorepmu->regs + PM_EVTYPE(i));
128 }
129 writeq_relaxed(PM_CR_ENABLE, uncorepmu->regs + PM_CR);
130 }
131
fujitsu_uncore_handle_irq(int irq_num,void * data)132 static irqreturn_t fujitsu_uncore_handle_irq(int irq_num, void *data)
133 {
134 struct uncore_pmu *uncorepmu = data;
135 /* Read the overflow status register */
136 long status = readq_relaxed(uncorepmu->regs + PM_OVSR);
137 int idx;
138
139 if (status == 0)
140 return IRQ_NONE;
141
142 /* Clear the bits we read on the overflow status register */
143 writeq_relaxed(status, uncorepmu->regs + PM_OVSR);
144
145 for_each_set_bit(idx, &status, uncorepmu->num_counters) {
146 struct perf_event *event;
147
148 event = uncorepmu->events[idx];
149 if (!event)
150 continue;
151
152 fujitsu_uncore_counter_update(event);
153 }
154
155 return IRQ_HANDLED;
156 }
157
fujitsu_uncore_pmu_enable(struct pmu * pmu)158 static void fujitsu_uncore_pmu_enable(struct pmu *pmu)
159 {
160 writeq_relaxed(PM_CR_ENABLE, to_uncore_pmu(pmu)->regs + PM_CR);
161 }
162
fujitsu_uncore_pmu_disable(struct pmu * pmu)163 static void fujitsu_uncore_pmu_disable(struct pmu *pmu)
164 {
165 writeq_relaxed(0, to_uncore_pmu(pmu)->regs + PM_CR);
166 }
167
fujitsu_uncore_validate_event_group(struct perf_event * event)168 static bool fujitsu_uncore_validate_event_group(struct perf_event *event)
169 {
170 struct uncore_pmu *uncorepmu = to_uncore_pmu(event->pmu);
171 struct perf_event *leader = event->group_leader;
172 struct perf_event *sibling;
173 int counters = 1;
174
175 if (leader == event)
176 return true;
177
178 if (leader->pmu == event->pmu)
179 counters++;
180
181 for_each_sibling_event(sibling, leader) {
182 if (sibling->pmu == event->pmu)
183 counters++;
184 }
185
186 /*
187 * If the group requires more counters than the HW has, it
188 * cannot ever be scheduled.
189 */
190 return counters <= uncorepmu->num_counters;
191 }
192
fujitsu_uncore_event_init(struct perf_event * event)193 static int fujitsu_uncore_event_init(struct perf_event *event)
194 {
195 struct uncore_pmu *uncorepmu = to_uncore_pmu(event->pmu);
196 struct hw_perf_event *hwc = &event->hw;
197
198 /* Is the event for this PMU? */
199 if (event->attr.type != event->pmu->type)
200 return -ENOENT;
201
202 /*
203 * Sampling not supported since these events are not
204 * core-attributable.
205 */
206 if (is_sampling_event(event))
207 return -EINVAL;
208
209 /*
210 * Task mode not available, we run the counters as socket counters,
211 * not attributable to any CPU and therefore cannot attribute per-task.
212 */
213 if (event->cpu < 0)
214 return -EINVAL;
215
216 /* Validate the group */
217 if (!fujitsu_uncore_validate_event_group(event))
218 return -EINVAL;
219
220 hwc->idx = -1;
221
222 event->cpu = uncorepmu->cpu;
223
224 return 0;
225 }
226
fujitsu_uncore_event_start(struct perf_event * event,int flags)227 static void fujitsu_uncore_event_start(struct perf_event *event, int flags)
228 {
229 struct hw_perf_event *hwc = &event->hw;
230
231 hwc->state = 0;
232 fujitsu_uncore_counter_start(event);
233 }
234
fujitsu_uncore_event_stop(struct perf_event * event,int flags)235 static void fujitsu_uncore_event_stop(struct perf_event *event, int flags)
236 {
237 struct hw_perf_event *hwc = &event->hw;
238
239 if (hwc->state & PERF_HES_STOPPED)
240 return;
241
242 fujitsu_uncore_counter_stop(event);
243 if (flags & PERF_EF_UPDATE)
244 fujitsu_uncore_counter_update(event);
245 hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
246 }
247
fujitsu_uncore_event_add(struct perf_event * event,int flags)248 static int fujitsu_uncore_event_add(struct perf_event *event, int flags)
249 {
250 struct uncore_pmu *uncorepmu = to_uncore_pmu(event->pmu);
251 struct hw_perf_event *hwc = &event->hw;
252 int idx;
253
254 /* Try to allocate a counter. */
255 idx = bitmap_find_free_region(uncorepmu->used_mask, uncorepmu->num_counters, 0);
256 if (idx < 0)
257 /* The counters are all in use. */
258 return -EAGAIN;
259
260 hwc->idx = idx;
261 hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
262 uncorepmu->events[idx] = event;
263
264 if (flags & PERF_EF_START)
265 fujitsu_uncore_event_start(event, 0);
266
267 /* Propagate changes to the userspace mapping. */
268 perf_event_update_userpage(event);
269
270 return 0;
271 }
272
fujitsu_uncore_event_del(struct perf_event * event,int flags)273 static void fujitsu_uncore_event_del(struct perf_event *event, int flags)
274 {
275 struct uncore_pmu *uncorepmu = to_uncore_pmu(event->pmu);
276 struct hw_perf_event *hwc = &event->hw;
277
278 /* Stop and clean up */
279 fujitsu_uncore_event_stop(event, flags | PERF_EF_UPDATE);
280 uncorepmu->events[hwc->idx] = NULL;
281 bitmap_release_region(uncorepmu->used_mask, hwc->idx, 0);
282
283 /* Propagate changes to the userspace mapping. */
284 perf_event_update_userpage(event);
285 }
286
fujitsu_uncore_event_read(struct perf_event * event)287 static void fujitsu_uncore_event_read(struct perf_event *event)
288 {
289 fujitsu_uncore_counter_update(event);
290 }
291
292 #define UNCORE_PMU_FORMAT_ATTR(_name, _config) \
293 (&((struct dev_ext_attribute[]) { \
294 { .attr = __ATTR(_name, 0444, device_show_string, NULL), \
295 .var = (void *)_config, } \
296 })[0].attr.attr)
297
298 static struct attribute *fujitsu_uncore_pmu_formats[] = {
299 UNCORE_PMU_FORMAT_ATTR(event, "config:0-7"),
300 NULL
301 };
302
303 static const struct attribute_group fujitsu_uncore_pmu_format_group = {
304 .name = "format",
305 .attrs = fujitsu_uncore_pmu_formats,
306 };
307
fujitsu_uncore_pmu_event_show(struct device * dev,struct device_attribute * attr,char * page)308 static ssize_t fujitsu_uncore_pmu_event_show(struct device *dev,
309 struct device_attribute *attr, char *page)
310 {
311 struct perf_pmu_events_attr *pmu_attr;
312
313 pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
314 return sysfs_emit(page, "event=0x%02llx\n", pmu_attr->id);
315 }
316
317 #define MAC_EVENT_ATTR(_name, _id) \
318 PMU_EVENT_ATTR_ID(_name, fujitsu_uncore_pmu_event_show, _id)
319
320 static struct attribute *fujitsu_uncore_mac_pmu_events[] = {
321 MAC_EVENT_ATTR(cycles, 0x00),
322 MAC_EVENT_ATTR(read-count, 0x10),
323 MAC_EVENT_ATTR(read-count-request, 0x11),
324 MAC_EVENT_ATTR(read-count-return, 0x12),
325 MAC_EVENT_ATTR(read-count-request-pftgt, 0x13),
326 MAC_EVENT_ATTR(read-count-request-normal, 0x14),
327 MAC_EVENT_ATTR(read-count-return-pftgt-hit, 0x15),
328 MAC_EVENT_ATTR(read-count-return-pftgt-miss, 0x16),
329 MAC_EVENT_ATTR(read-wait, 0x17),
330 MAC_EVENT_ATTR(write-count, 0x20),
331 MAC_EVENT_ATTR(write-count-write, 0x21),
332 MAC_EVENT_ATTR(write-count-pwrite, 0x22),
333 MAC_EVENT_ATTR(memory-read-count, 0x40),
334 MAC_EVENT_ATTR(memory-write-count, 0x50),
335 MAC_EVENT_ATTR(memory-pwrite-count, 0x60),
336 MAC_EVENT_ATTR(ea-mac, 0x80),
337 MAC_EVENT_ATTR(ea-memory, 0x90),
338 MAC_EVENT_ATTR(ea-memory-mac-write, 0x92),
339 MAC_EVENT_ATTR(ea-ha, 0xa0),
340 NULL
341 };
342
343 #define PCI_EVENT_ATTR(_name, _id) \
344 PMU_EVENT_ATTR_ID(_name, fujitsu_uncore_pmu_event_show, _id)
345
346 static struct attribute *fujitsu_uncore_pci_pmu_events[] = {
347 PCI_EVENT_ATTR(pci-port0-cycles, 0x00),
348 PCI_EVENT_ATTR(pci-port0-read-count, 0x10),
349 PCI_EVENT_ATTR(pci-port0-read-count-bus, 0x14),
350 PCI_EVENT_ATTR(pci-port0-write-count, 0x20),
351 PCI_EVENT_ATTR(pci-port0-write-count-bus, 0x24),
352 PCI_EVENT_ATTR(pci-port1-cycles, 0x40),
353 PCI_EVENT_ATTR(pci-port1-read-count, 0x50),
354 PCI_EVENT_ATTR(pci-port1-read-count-bus, 0x54),
355 PCI_EVENT_ATTR(pci-port1-write-count, 0x60),
356 PCI_EVENT_ATTR(pci-port1-write-count-bus, 0x64),
357 PCI_EVENT_ATTR(ea-pci, 0x80),
358 NULL
359 };
360
361 static const struct attribute_group fujitsu_uncore_mac_pmu_events_group = {
362 .name = "events",
363 .attrs = fujitsu_uncore_mac_pmu_events,
364 };
365
366 static const struct attribute_group fujitsu_uncore_pci_pmu_events_group = {
367 .name = "events",
368 .attrs = fujitsu_uncore_pci_pmu_events,
369 };
370
cpumask_show(struct device * dev,struct device_attribute * attr,char * buf)371 static ssize_t cpumask_show(struct device *dev,
372 struct device_attribute *attr, char *buf)
373 {
374 struct uncore_pmu *uncorepmu = to_uncore_pmu(dev_get_drvdata(dev));
375
376 return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(uncorepmu->cpu)));
377 }
378 static DEVICE_ATTR_RO(cpumask);
379
380 static struct attribute *fujitsu_uncore_pmu_cpumask_attrs[] = {
381 &dev_attr_cpumask.attr,
382 NULL
383 };
384
385 static const struct attribute_group fujitsu_uncore_pmu_cpumask_attr_group = {
386 .attrs = fujitsu_uncore_pmu_cpumask_attrs,
387 };
388
389 static const struct attribute_group *fujitsu_uncore_mac_pmu_attr_grps[] = {
390 &fujitsu_uncore_pmu_format_group,
391 &fujitsu_uncore_mac_pmu_events_group,
392 &fujitsu_uncore_pmu_cpumask_attr_group,
393 NULL
394 };
395
396 static const struct attribute_group *fujitsu_uncore_pci_pmu_attr_grps[] = {
397 &fujitsu_uncore_pmu_format_group,
398 &fujitsu_uncore_pci_pmu_events_group,
399 &fujitsu_uncore_pmu_cpumask_attr_group,
400 NULL
401 };
402
fujitsu_uncore_pmu_migrate(struct uncore_pmu * uncorepmu,unsigned int cpu)403 static void fujitsu_uncore_pmu_migrate(struct uncore_pmu *uncorepmu, unsigned int cpu)
404 {
405 perf_pmu_migrate_context(&uncorepmu->pmu, uncorepmu->cpu, cpu);
406 irq_set_affinity(uncorepmu->irq, cpumask_of(cpu));
407 uncorepmu->cpu = cpu;
408 }
409
fujitsu_uncore_pmu_online_cpu(unsigned int cpu,struct hlist_node * cpuhp_node)410 static int fujitsu_uncore_pmu_online_cpu(unsigned int cpu, struct hlist_node *cpuhp_node)
411 {
412 struct uncore_pmu *uncorepmu;
413 int node;
414
415 uncorepmu = hlist_entry_safe(cpuhp_node, struct uncore_pmu, node);
416 node = dev_to_node(uncorepmu->dev);
417 if (cpu_to_node(uncorepmu->cpu) != node && cpu_to_node(cpu) == node)
418 fujitsu_uncore_pmu_migrate(uncorepmu, cpu);
419
420 return 0;
421 }
422
fujitsu_uncore_pmu_offline_cpu(unsigned int cpu,struct hlist_node * cpuhp_node)423 static int fujitsu_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *cpuhp_node)
424 {
425 struct uncore_pmu *uncorepmu;
426 unsigned int target;
427 int node;
428
429 uncorepmu = hlist_entry_safe(cpuhp_node, struct uncore_pmu, node);
430 if (cpu != uncorepmu->cpu)
431 return 0;
432
433 node = dev_to_node(uncorepmu->dev);
434 target = cpumask_any_and_but(cpumask_of_node(node), cpu_online_mask, cpu);
435 if (target >= nr_cpu_ids)
436 target = cpumask_any_but(cpu_online_mask, cpu);
437
438 if (target < nr_cpu_ids)
439 fujitsu_uncore_pmu_migrate(uncorepmu, target);
440
441 return 0;
442 }
443
fujitsu_uncore_pmu_probe(struct platform_device * pdev)444 static int fujitsu_uncore_pmu_probe(struct platform_device *pdev)
445 {
446 struct device *dev = &pdev->dev;
447 unsigned long device_type = (unsigned long)device_get_match_data(dev);
448 const struct attribute_group **attr_groups;
449 struct uncore_pmu *uncorepmu;
450 struct resource *memrc;
451 size_t alloc_size;
452 char *name;
453 int ret;
454 int irq;
455 u64 uid;
456
457 ret = acpi_dev_uid_to_integer(ACPI_COMPANION(dev), &uid);
458 if (ret)
459 return dev_err_probe(dev, ret, "unable to read ACPI uid\n");
460
461 uncorepmu = devm_kzalloc(dev, sizeof(*uncorepmu), GFP_KERNEL);
462 if (!uncorepmu)
463 return -ENOMEM;
464 uncorepmu->dev = dev;
465 uncorepmu->cpu = cpumask_local_spread(0, dev_to_node(dev));
466 platform_set_drvdata(pdev, uncorepmu);
467
468 switch (device_type) {
469 case FUJITSU_UNCORE_PMU_MAC:
470 uncorepmu->num_counters = MAC_NUM_COUNTERS;
471 attr_groups = fujitsu_uncore_mac_pmu_attr_grps;
472 name = devm_kasprintf(dev, GFP_KERNEL, "mac_iod%llu_mac%llu_ch%llu",
473 (uid >> 8) & 0xF, (uid >> 4) & 0xF, uid & 0xF);
474 break;
475 case FUJITSU_UNCORE_PMU_PCI:
476 uncorepmu->num_counters = PCI_NUM_COUNTERS;
477 attr_groups = fujitsu_uncore_pci_pmu_attr_grps;
478 name = devm_kasprintf(dev, GFP_KERNEL, "pci_iod%llu_pci%llu",
479 (uid >> 4) & 0xF, uid & 0xF);
480 break;
481 default:
482 return dev_err_probe(dev, -EINVAL, "illegal device type: %lu\n", device_type);
483 }
484 if (!name)
485 return -ENOMEM;
486
487 uncorepmu->pmu = (struct pmu) {
488 .parent = dev,
489 .task_ctx_nr = perf_invalid_context,
490
491 .attr_groups = attr_groups,
492
493 .pmu_enable = fujitsu_uncore_pmu_enable,
494 .pmu_disable = fujitsu_uncore_pmu_disable,
495 .event_init = fujitsu_uncore_event_init,
496 .add = fujitsu_uncore_event_add,
497 .del = fujitsu_uncore_event_del,
498 .start = fujitsu_uncore_event_start,
499 .stop = fujitsu_uncore_event_stop,
500 .read = fujitsu_uncore_event_read,
501
502 .capabilities = PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT,
503 };
504
505 alloc_size = sizeof(uncorepmu->events[0]) * uncorepmu->num_counters;
506 uncorepmu->events = devm_kzalloc(dev, alloc_size, GFP_KERNEL);
507 if (!uncorepmu->events)
508 return -ENOMEM;
509
510 alloc_size = sizeof(uncorepmu->used_mask[0]) * BITS_TO_LONGS(uncorepmu->num_counters);
511 uncorepmu->used_mask = devm_kzalloc(dev, alloc_size, GFP_KERNEL);
512 if (!uncorepmu->used_mask)
513 return -ENOMEM;
514
515 uncorepmu->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &memrc);
516 if (IS_ERR(uncorepmu->regs))
517 return PTR_ERR(uncorepmu->regs);
518
519 fujitsu_uncore_init(uncorepmu);
520
521 irq = platform_get_irq(pdev, 0);
522 if (irq < 0)
523 return irq;
524
525 ret = devm_request_irq(dev, irq, fujitsu_uncore_handle_irq,
526 IRQF_NOBALANCING | IRQF_NO_THREAD,
527 name, uncorepmu);
528 if (ret)
529 return ret;
530
531 ret = irq_set_affinity(irq, cpumask_of(uncorepmu->cpu));
532 if (ret)
533 return dev_err_probe(dev, ret, "Failed to set irq affinity:%d\n", irq);
534
535 uncorepmu->irq = irq;
536
537 /* Add this instance to the list used by the offline callback */
538 ret = cpuhp_state_add_instance(uncore_pmu_cpuhp_state, &uncorepmu->node);
539 if (ret)
540 return dev_err_probe(dev, ret, "Error registering hotplug");
541
542 ret = perf_pmu_register(&uncorepmu->pmu, name, -1);
543 if (ret < 0) {
544 cpuhp_state_remove_instance_nocalls(uncore_pmu_cpuhp_state, &uncorepmu->node);
545 return dev_err_probe(dev, ret, "Failed to register %s PMU\n", name);
546 }
547
548 dev_dbg(dev, "Registered %s, type: %d\n", name, uncorepmu->pmu.type);
549
550 return 0;
551 }
552
fujitsu_uncore_pmu_remove(struct platform_device * pdev)553 static void fujitsu_uncore_pmu_remove(struct platform_device *pdev)
554 {
555 struct uncore_pmu *uncorepmu = platform_get_drvdata(pdev);
556
557 writeq_relaxed(0, uncorepmu->regs + PM_CR);
558
559 perf_pmu_unregister(&uncorepmu->pmu);
560 cpuhp_state_remove_instance_nocalls(uncore_pmu_cpuhp_state, &uncorepmu->node);
561 }
562
563 static const struct acpi_device_id fujitsu_uncore_pmu_acpi_match[] = {
564 { "FUJI200C", FUJITSU_UNCORE_PMU_MAC },
565 { "FUJI200D", FUJITSU_UNCORE_PMU_PCI },
566 { }
567 };
568 MODULE_DEVICE_TABLE(acpi, fujitsu_uncore_pmu_acpi_match);
569
570 static struct platform_driver fujitsu_uncore_pmu_driver = {
571 .driver = {
572 .name = "fujitsu-uncore-pmu",
573 .acpi_match_table = fujitsu_uncore_pmu_acpi_match,
574 .suppress_bind_attrs = true,
575 },
576 .probe = fujitsu_uncore_pmu_probe,
577 .remove = fujitsu_uncore_pmu_remove,
578 };
579
fujitsu_uncore_pmu_init(void)580 static int __init fujitsu_uncore_pmu_init(void)
581 {
582 int ret;
583
584 /* Install a hook to update the reader CPU in case it goes offline */
585 ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
586 "perf/fujitsu/uncore:online",
587 fujitsu_uncore_pmu_online_cpu,
588 fujitsu_uncore_pmu_offline_cpu);
589 if (ret < 0)
590 return ret;
591
592 uncore_pmu_cpuhp_state = ret;
593
594 ret = platform_driver_register(&fujitsu_uncore_pmu_driver);
595 if (ret)
596 cpuhp_remove_multi_state(uncore_pmu_cpuhp_state);
597
598 return ret;
599 }
600
fujitsu_uncore_pmu_exit(void)601 static void __exit fujitsu_uncore_pmu_exit(void)
602 {
603 platform_driver_unregister(&fujitsu_uncore_pmu_driver);
604 cpuhp_remove_multi_state(uncore_pmu_cpuhp_state);
605 }
606
607 module_init(fujitsu_uncore_pmu_init);
608 module_exit(fujitsu_uncore_pmu_exit);
609
610 MODULE_AUTHOR("Koichi Okuno <fj2767dz@fujitsu.com>");
611 MODULE_DESCRIPTION("Fujitsu Uncore PMU driver");
612 MODULE_LICENSE("GPL");
613