.. | .. |
---|
99 | 99 | cpumask_t cpu; |
---|
100 | 100 | struct hrtimer hrtimer; |
---|
101 | 101 | unsigned int active_events; |
---|
| 102 | + int id; |
---|
102 | 103 | struct device *dev; |
---|
103 | 104 | struct perf_event *mmdc_events[MMDC_NUM_COUNTERS]; |
---|
104 | 105 | struct hlist_node node; |
---|
.. | .. |
---|
433 | 434 | static int mmdc_pmu_init(struct mmdc_pmu *pmu_mmdc, |
---|
434 | 435 | void __iomem *mmdc_base, struct device *dev) |
---|
435 | 436 | { |
---|
436 | | - int mmdc_num; |
---|
437 | | - |
---|
438 | 437 | *pmu_mmdc = (struct mmdc_pmu) { |
---|
439 | 438 | .pmu = (struct pmu) { |
---|
440 | 439 | .task_ctx_nr = perf_invalid_context, |
---|
.. | .. |
---|
452 | 451 | .active_events = 0, |
---|
453 | 452 | }; |
---|
454 | 453 | |
---|
455 | | - mmdc_num = ida_simple_get(&mmdc_ida, 0, 0, GFP_KERNEL); |
---|
| 454 | + pmu_mmdc->id = ida_simple_get(&mmdc_ida, 0, 0, GFP_KERNEL); |
---|
456 | 455 | |
---|
457 | | - return mmdc_num; |
---|
| 456 | + return pmu_mmdc->id; |
---|
458 | 457 | } |
---|
459 | 458 | |
---|
460 | 459 | static int imx_mmdc_remove(struct platform_device *pdev) |
---|
461 | 460 | { |
---|
462 | 461 | struct mmdc_pmu *pmu_mmdc = platform_get_drvdata(pdev); |
---|
463 | 462 | |
---|
| 463 | + ida_simple_remove(&mmdc_ida, pmu_mmdc->id); |
---|
464 | 464 | cpuhp_state_remove_instance_nocalls(cpuhp_mmdc_state, &pmu_mmdc->node); |
---|
465 | 465 | perf_pmu_unregister(&pmu_mmdc->pmu); |
---|
466 | 466 | iounmap(pmu_mmdc->mmdc_base); |
---|
.. | .. |
---|
474 | 474 | { |
---|
475 | 475 | struct mmdc_pmu *pmu_mmdc; |
---|
476 | 476 | char *name; |
---|
477 | | - int mmdc_num; |
---|
478 | 477 | int ret; |
---|
479 | 478 | const struct of_device_id *of_id = |
---|
480 | 479 | of_match_device(imx_mmdc_dt_ids, &pdev->dev); |
---|
.. | .. |
---|
497 | 496 | cpuhp_mmdc_state = ret; |
---|
498 | 497 | } |
---|
499 | 498 | |
---|
500 | | - mmdc_num = mmdc_pmu_init(pmu_mmdc, mmdc_base, &pdev->dev); |
---|
501 | | - pmu_mmdc->mmdc_ipg_clk = mmdc_ipg_clk; |
---|
502 | | - if (mmdc_num == 0) |
---|
503 | | - name = "mmdc"; |
---|
504 | | - else |
---|
505 | | - name = devm_kasprintf(&pdev->dev, |
---|
506 | | - GFP_KERNEL, "mmdc%d", mmdc_num); |
---|
| 499 | + ret = mmdc_pmu_init(pmu_mmdc, mmdc_base, &pdev->dev); |
---|
| 500 | + if (ret < 0) |
---|
| 501 | + goto pmu_free; |
---|
507 | 502 | |
---|
| 503 | + name = devm_kasprintf(&pdev->dev, |
---|
| 504 | + GFP_KERNEL, "mmdc%d", ret); |
---|
| 505 | + |
---|
| 506 | + pmu_mmdc->mmdc_ipg_clk = mmdc_ipg_clk; |
---|
508 | 507 | pmu_mmdc->devtype_data = (struct fsl_mmdc_devtype_data *)of_id->data; |
---|
509 | 508 | |
---|
510 | 509 | hrtimer_init(&pmu_mmdc->hrtimer, CLOCK_MONOTONIC, |
---|
.. | .. |
---|
525 | 524 | |
---|
526 | 525 | pmu_register_err: |
---|
527 | 526 | pr_warn("MMDC Perf PMU failed (%d), disabled\n", ret); |
---|
| 527 | + ida_simple_remove(&mmdc_ida, pmu_mmdc->id); |
---|
528 | 528 | cpuhp_state_remove_instance_nocalls(cpuhp_mmdc_state, &pmu_mmdc->node); |
---|
529 | 529 | hrtimer_cancel(&pmu_mmdc->hrtimer); |
---|
530 | 530 | pmu_free: |
---|