| .. | .. |
|---|
| 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: |
|---|