Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1e1b84b0 authored by Angus Chen's avatar Angus Chen Committed by Greg Kroah-Hartman
Browse files

ARM: imx: Call ida_simple_remove() for ida_simple_get



[ Upstream commit ebeb49f43c8952f12aa20f03f00d7009edc2d1c5 ]

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: e76bdfd7 ("ARM: imx: Added perf functionality to mmdc driver")
Signed-off-by: default avatarAngus Chen <angus.chen@jaguarmicro.com>
Signed-off-by: default avatarShawn Guo <shawnguo@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent b0a1b2f3
Loading
Loading
Loading
Loading
+12 −12
Original line number Original line Diff line number Diff line
@@ -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,
	name = devm_kasprintf(&pdev->dev,
				GFP_KERNEL, "mmdc%d", mmdc_num);
				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: