ARM: imx: Call ida_simple_remove() for ida_simple_get

[ Upstream commit ebeb49f43c ]

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: e76bdfd740 ("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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Angus Chen 2023-01-05 14:11:23 +08:00 committed by Greg Kroah-Hartman
parent 7f02f32ee6
commit 1e0a7b41f5
1 changed files with 12 additions and 12 deletions

View File

@ -99,6 +99,7 @@ struct mmdc_pmu {
cpumask_t cpu; cpumask_t cpu;
struct hrtimer hrtimer; struct hrtimer hrtimer;
unsigned int active_events; unsigned int active_events;
int id;
struct device *dev; struct device *dev;
struct perf_event *mmdc_events[MMDC_NUM_COUNTERS]; struct perf_event *mmdc_events[MMDC_NUM_COUNTERS];
struct hlist_node node; 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, static int mmdc_pmu_init(struct mmdc_pmu *pmu_mmdc,
void __iomem *mmdc_base, struct device *dev) void __iomem *mmdc_base, struct device *dev)
{ {
int mmdc_num;
*pmu_mmdc = (struct mmdc_pmu) { *pmu_mmdc = (struct mmdc_pmu) {
.pmu = (struct pmu) { .pmu = (struct pmu) {
.task_ctx_nr = perf_invalid_context, .task_ctx_nr = perf_invalid_context,
@ -452,15 +451,16 @@ static int mmdc_pmu_init(struct mmdc_pmu *pmu_mmdc,
.active_events = 0, .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) static int imx_mmdc_remove(struct platform_device *pdev)
{ {
struct mmdc_pmu *pmu_mmdc = platform_get_drvdata(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); cpuhp_state_remove_instance_nocalls(cpuhp_mmdc_state, &pmu_mmdc->node);
perf_pmu_unregister(&pmu_mmdc->pmu); perf_pmu_unregister(&pmu_mmdc->pmu);
iounmap(pmu_mmdc->mmdc_base); 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; struct mmdc_pmu *pmu_mmdc;
char *name; char *name;
int mmdc_num;
int ret; int ret;
const struct of_device_id *of_id = const struct of_device_id *of_id =
of_match_device(imx_mmdc_dt_ids, &pdev->dev); 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; cpuhp_mmdc_state = ret;
} }
mmdc_num = mmdc_pmu_init(pmu_mmdc, mmdc_base, &pdev->dev); ret = mmdc_pmu_init(pmu_mmdc, mmdc_base, &pdev->dev);
pmu_mmdc->mmdc_ipg_clk = mmdc_ipg_clk; if (ret < 0)
if (mmdc_num == 0) goto pmu_free;
name = "mmdc";
else
name = devm_kasprintf(&pdev->dev,
GFP_KERNEL, "mmdc%d", mmdc_num);
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; pmu_mmdc->devtype_data = (struct fsl_mmdc_devtype_data *)of_id->data;
hrtimer_init(&pmu_mmdc->hrtimer, CLOCK_MONOTONIC, 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: pmu_register_err:
pr_warn("MMDC Perf PMU failed (%d), disabled\n", ret); 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); cpuhp_state_remove_instance_nocalls(cpuhp_mmdc_state, &pmu_mmdc->node);
hrtimer_cancel(&pmu_mmdc->hrtimer); hrtimer_cancel(&pmu_mmdc->hrtimer);
pmu_free: pmu_free: