ARM: imx: Call ida_simple_remove() for ida_simple_get
authorAngus Chen <angus.chen@jaguarmicro.com>
Thu, 5 Jan 2023 06:11:23 +0000 (14:11 +0800)
committerShawn Guo <shawnguo@kernel.org>
Wed, 25 Jan 2023 23:55:53 +0000 (07:55 +0800)
The function call ida_simple_get maybe fail,we should deal with it.
And if ida_simple_get success ,it need to call ida_simple_remove also.
BTW,devm_kasprintf can handle id is zero for consistency.

Fixes: e76bdfd7403a ("ARM: imx: Added perf functionality to mmdc driver")
Signed-off-by: Angus Chen <angus.chen@jaguarmicro.com>
Signed-off-by: Shawn Guo <shawnguo@kernel.org>
arch/arm/mach-imx/mmdc.c

index af12668..b9efe9d 100644 (file)
@@ -99,6 +99,7 @@ struct mmdc_pmu {
        cpumask_t cpu;
        struct hrtimer hrtimer;
        unsigned int active_events;
+       int id;
        struct device *dev;
        struct perf_event *mmdc_events[MMDC_NUM_COUNTERS];
        struct hlist_node node;
@@ -433,8 +434,6 @@ static enum hrtimer_restart mmdc_pmu_timer_handler(struct hrtimer *hrtimer)
 static int mmdc_pmu_init(struct mmdc_pmu *pmu_mmdc,
                void __iomem *mmdc_base, struct device *dev)
 {
-       int mmdc_num;
-
        *pmu_mmdc = (struct mmdc_pmu) {
                .pmu = (struct pmu) {
                        .task_ctx_nr    = perf_invalid_context,
@@ -452,15 +451,16 @@ static int mmdc_pmu_init(struct mmdc_pmu *pmu_mmdc,
                .active_events = 0,
        };
 
-       mmdc_num = ida_simple_get(&mmdc_ida, 0, 0, GFP_KERNEL);
+       pmu_mmdc->id = ida_simple_get(&mmdc_ida, 0, 0, GFP_KERNEL);
 
-       return mmdc_num;
+       return pmu_mmdc->id;
 }
 
 static int imx_mmdc_remove(struct platform_device *pdev)
 {
        struct mmdc_pmu *pmu_mmdc = platform_get_drvdata(pdev);
 
+       ida_simple_remove(&mmdc_ida, pmu_mmdc->id);
        cpuhp_state_remove_instance_nocalls(cpuhp_mmdc_state, &pmu_mmdc->node);
        perf_pmu_unregister(&pmu_mmdc->pmu);
        iounmap(pmu_mmdc->mmdc_base);
@@ -474,7 +474,6 @@ static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_b
 {
        struct mmdc_pmu *pmu_mmdc;
        char *name;
-       int mmdc_num;
        int ret;
        const struct of_device_id *of_id =
                of_match_device(imx_mmdc_dt_ids, &pdev->dev);
@@ -497,14 +496,14 @@ static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_b
                cpuhp_mmdc_state = ret;
        }
 
-       mmdc_num = mmdc_pmu_init(pmu_mmdc, mmdc_base, &pdev->dev);
-       pmu_mmdc->mmdc_ipg_clk = mmdc_ipg_clk;
-       if (mmdc_num == 0)
-               name = "mmdc";
-       else
-               name = devm_kasprintf(&pdev->dev,
-                               GFP_KERNEL, "mmdc%d", mmdc_num);
+       ret = mmdc_pmu_init(pmu_mmdc, mmdc_base, &pdev->dev);
+       if (ret < 0)
+               goto  pmu_free;
 
+       name = devm_kasprintf(&pdev->dev,
+                               GFP_KERNEL, "mmdc%d", ret);
+
+       pmu_mmdc->mmdc_ipg_clk = mmdc_ipg_clk;
        pmu_mmdc->devtype_data = (struct fsl_mmdc_devtype_data *)of_id->data;
 
        hrtimer_init(&pmu_mmdc->hrtimer, CLOCK_MONOTONIC,
@@ -525,6 +524,7 @@ static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_b
 
 pmu_register_err:
        pr_warn("MMDC Perf PMU failed (%d), disabled\n", ret);
+       ida_simple_remove(&mmdc_ida, pmu_mmdc->id);
        cpuhp_state_remove_instance_nocalls(cpuhp_mmdc_state, &pmu_mmdc->node);
        hrtimer_cancel(&pmu_mmdc->hrtimer);
 pmu_free: