Commit ce789307 authored by Mark Brown's avatar Mark Brown

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
...@@ -418,13 +418,6 @@ int mt8188_afe_init_clock(struct mtk_base_afe *afe) ...@@ -418,13 +418,6 @@ int mt8188_afe_init_clock(struct mtk_base_afe *afe)
return 0; 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 mt8188_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk)
{ {
int ret; int ret;
......
...@@ -100,7 +100,6 @@ int mt8188_afe_get_mclk_source_clk_id(int sel); ...@@ -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_mclk_source_rate(struct mtk_base_afe *afe, int apll);
int mt8188_afe_get_default_mclk_source_by_rate(int rate); int mt8188_afe_get_default_mclk_source_by_rate(int rate);
int mt8188_afe_init_clock(struct mtk_base_afe *afe); 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); 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); 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, int mt8188_afe_set_clk_rate(struct mtk_base_afe *afe, struct clk *clk,
......
...@@ -3185,10 +3185,6 @@ static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev) ...@@ -3185,10 +3185,6 @@ static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev)
if (ret) if (ret)
return dev_err_probe(dev, ret, "init clock error"); 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); spin_lock_init(&afe_priv->afe_ctrl_lock);
mutex_init(&afe->irq_alloc_lock); mutex_init(&afe->irq_alloc_lock);
......
...@@ -138,6 +138,29 @@ static const struct afe_gate aud_clks[CLK_AUD_NR_CLK] = { ...@@ -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), 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) int mt8188_audsys_clk_register(struct mtk_base_afe *afe)
{ {
struct mt8188_afe_private *afe_priv = afe->platform_priv; struct mt8188_afe_private *afe_priv = afe->platform_priv;
...@@ -179,27 +202,5 @@ int mt8188_audsys_clk_register(struct mtk_base_afe *afe) ...@@ -179,27 +202,5 @@ int mt8188_audsys_clk_register(struct mtk_base_afe *afe)
afe_priv->lookup[i] = cl; afe_priv->lookup[i] = cl;
} }
return 0; return devm_add_action_or_reset(afe->dev, mt8188_audsys_clk_unregister, afe);
}
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);
}
} }
...@@ -10,6 +10,5 @@ ...@@ -10,6 +10,5 @@
#define _MT8188_AUDSYS_CLK_H_ #define _MT8188_AUDSYS_CLK_H_
int mt8188_audsys_clk_register(struct mtk_base_afe *afe); int mt8188_audsys_clk_register(struct mtk_base_afe *afe);
void mt8188_audsys_clk_unregister(struct mtk_base_afe *afe);
#endif #endif
...@@ -410,11 +410,6 @@ int mt8195_afe_init_clock(struct mtk_base_afe *afe) ...@@ -410,11 +410,6 @@ int mt8195_afe_init_clock(struct mtk_base_afe *afe)
return 0; return 0;
} }
void mt8195_afe_deinit_clock(struct mtk_base_afe *afe)
{
mt8195_audsys_clk_unregister(afe);
}
int mt8195_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk) int mt8195_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk)
{ {
int ret; int ret;
......
...@@ -101,7 +101,6 @@ int mt8195_afe_get_mclk_source_clk_id(int sel); ...@@ -101,7 +101,6 @@ int mt8195_afe_get_mclk_source_clk_id(int sel);
int mt8195_afe_get_mclk_source_rate(struct mtk_base_afe *afe, int apll); int mt8195_afe_get_mclk_source_rate(struct mtk_base_afe *afe, int apll);
int mt8195_afe_get_default_mclk_source_by_rate(int rate); int mt8195_afe_get_default_mclk_source_by_rate(int rate);
int mt8195_afe_init_clock(struct mtk_base_afe *afe); int mt8195_afe_init_clock(struct mtk_base_afe *afe);
void mt8195_afe_deinit_clock(struct mtk_base_afe *afe);
int mt8195_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk); int mt8195_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk);
void mt8195_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk); void mt8195_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk);
int mt8195_afe_prepare_clk(struct mtk_base_afe *afe, struct clk *clk); int mt8195_afe_prepare_clk(struct mtk_base_afe *afe, struct clk *clk);
......
...@@ -3255,15 +3255,11 @@ static int mt8195_afe_pcm_dev_probe(struct platform_device *pdev) ...@@ -3255,15 +3255,11 @@ static int mt8195_afe_pcm_dev_probe(struct platform_device *pdev)
static void mt8195_afe_pcm_dev_remove(struct platform_device *pdev) static void mt8195_afe_pcm_dev_remove(struct platform_device *pdev)
{ {
struct mtk_base_afe *afe = platform_get_drvdata(pdev);
snd_soc_unregister_component(&pdev->dev); snd_soc_unregister_component(&pdev->dev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev)) if (!pm_runtime_status_suspended(&pdev->dev))
mt8195_afe_runtime_suspend(&pdev->dev); mt8195_afe_runtime_suspend(&pdev->dev);
mt8195_afe_deinit_clock(afe);
} }
static const struct of_device_id mt8195_afe_pcm_dt_match[] = { static const struct of_device_id mt8195_afe_pcm_dt_match[] = {
......
...@@ -148,6 +148,29 @@ static const struct afe_gate aud_clks[CLK_AUD_NR_CLK] = { ...@@ -148,6 +148,29 @@ static const struct afe_gate aud_clks[CLK_AUD_NR_CLK] = {
GATE_AUD6(CLK_AUD_GASRC19, "aud_gasrc19", "top_asm_h", 19), GATE_AUD6(CLK_AUD_GASRC19, "aud_gasrc19", "top_asm_h", 19),
}; };
static void mt8195_audsys_clk_unregister(void *data)
{
struct mtk_base_afe *afe = data;
struct mt8195_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 mt8195_audsys_clk_register(struct mtk_base_afe *afe) int mt8195_audsys_clk_register(struct mtk_base_afe *afe)
{ {
struct mt8195_afe_private *afe_priv = afe->platform_priv; struct mt8195_afe_private *afe_priv = afe->platform_priv;
...@@ -188,27 +211,5 @@ int mt8195_audsys_clk_register(struct mtk_base_afe *afe) ...@@ -188,27 +211,5 @@ int mt8195_audsys_clk_register(struct mtk_base_afe *afe)
afe_priv->lookup[i] = cl; afe_priv->lookup[i] = cl;
} }
return 0; return devm_add_action_or_reset(afe->dev, mt8195_audsys_clk_unregister, afe);
}
void mt8195_audsys_clk_unregister(struct mtk_base_afe *afe)
{
struct mt8195_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);
}
} }
...@@ -10,6 +10,5 @@ ...@@ -10,6 +10,5 @@
#define _MT8195_AUDSYS_CLK_H_ #define _MT8195_AUDSYS_CLK_H_
int mt8195_audsys_clk_register(struct mtk_base_afe *afe); int mt8195_audsys_clk_register(struct mtk_base_afe *afe);
void mt8195_audsys_clk_unregister(struct mtk_base_afe *afe);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment