Unverified Commit ce789307 authored by Mark Brown's avatar Mark Brown
Browse files

ASoC: mediatek: fix use-after-free in driver remove

Merge series from Trevor Wu <trevor.wu@mediatek.com>:

These patches concern modifications made in mt8186[1]. The clock
unregistration mechanism used in mt8188 and mt8195 is similar with
mt8186, resulting in the same problem existing within the driver.
Therefore, the solution has also been applied to these two platforms.

[1] https://lore.kernel.org/all/20230511092437.1.I31cceffc8c45bb1af16eb613e197b3df92cdc19e@changeid/
parents 524306c3 dc93f0dc
Loading
Loading
Loading
Loading
+0 −7
Original line number Diff line number Diff line
@@ -418,13 +418,6 @@ int mt8188_afe_init_clock(struct mtk_base_afe *afe)
	return 0;
}

void mt8188_afe_deinit_clock(void *priv)
{
	struct mtk_base_afe *afe = priv;

	mt8188_audsys_clk_unregister(afe);
}

int mt8188_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk)
{
	int ret;
+0 −1
Original line number Diff line number Diff line
@@ -100,7 +100,6 @@ int mt8188_afe_get_mclk_source_clk_id(int sel);
int mt8188_afe_get_mclk_source_rate(struct mtk_base_afe *afe, int apll);
int mt8188_afe_get_default_mclk_source_by_rate(int rate);
int mt8188_afe_init_clock(struct mtk_base_afe *afe);
void mt8188_afe_deinit_clock(void *priv);
int mt8188_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk);
void mt8188_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk);
int mt8188_afe_set_clk_rate(struct mtk_base_afe *afe, struct clk *clk,
+0 −4
Original line number Diff line number Diff line
@@ -3185,10 +3185,6 @@ static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev)
	if (ret)
		return dev_err_probe(dev, ret, "init clock error");

	ret = devm_add_action_or_reset(dev, mt8188_afe_deinit_clock, (void *)afe);
	if (ret)
		return ret;

	spin_lock_init(&afe_priv->afe_ctrl_lock);

	mutex_init(&afe->irq_alloc_lock);
+24 −23
Original line number Diff line number Diff line
@@ -138,6 +138,29 @@ static const struct afe_gate aud_clks[CLK_AUD_NR_CLK] = {
	GATE_AUD6(CLK_AUD_GASRC11, "aud_gasrc11", "top_asm_h", 11),
};

static void mt8188_audsys_clk_unregister(void *data)
{
	struct mtk_base_afe *afe = data;
	struct mt8188_afe_private *afe_priv = afe->platform_priv;
	struct clk *clk;
	struct clk_lookup *cl;
	int i;

	if (!afe_priv)
		return;

	for (i = 0; i < CLK_AUD_NR_CLK; i++) {
		cl = afe_priv->lookup[i];
		if (!cl)
			continue;

		clk = cl->clk;
		clk_unregister_gate(clk);

		clkdev_drop(cl);
	}
}

int mt8188_audsys_clk_register(struct mtk_base_afe *afe)
{
	struct mt8188_afe_private *afe_priv = afe->platform_priv;
@@ -179,27 +202,5 @@ int mt8188_audsys_clk_register(struct mtk_base_afe *afe)
		afe_priv->lookup[i] = cl;
	}

	return 0;
}

void mt8188_audsys_clk_unregister(struct mtk_base_afe *afe)
{
	struct mt8188_afe_private *afe_priv = afe->platform_priv;
	struct clk *clk;
	struct clk_lookup *cl;
	int i;

	if (!afe_priv)
		return;

	for (i = 0; i < CLK_AUD_NR_CLK; i++) {
		cl = afe_priv->lookup[i];
		if (!cl)
			continue;

		clk = cl->clk;
		clk_unregister_gate(clk);

		clkdev_drop(cl);
	}
	return devm_add_action_or_reset(afe->dev, mt8188_audsys_clk_unregister, afe);
}
+0 −1
Original line number Diff line number Diff line
@@ -10,6 +10,5 @@
#define _MT8188_AUDSYS_CLK_H_

int mt8188_audsys_clk_register(struct mtk_base_afe *afe);
void mt8188_audsys_clk_unregister(struct mtk_base_afe *afe);

#endif
Loading