Commit cb2f97d8 authored by Kuninori Morimoto's avatar Kuninori Morimoto Committed by Mark Brown

ASoC: rsnd: adg: use more simple method for null_clk

commit 965386c9 ("ASoC: rsnd: call unregister for null_hw when
removed") tried unregister null_clk, but it has some issues.

1st issue is kernel will indicate below message when unregistering,
because of its timing. unregistering should be happen after clk_disable().

	clk_unregister: unregistering prepared clock: rsnd_adg_null

2nd issue is, it is using priv->null_clk, but it should be adg->null_clk.

3rd issue is it is using very complex clk registering method.
more simple clk_register/unregister_fixed_rate() should be OK.

This patch fixes these.

Fixes: 965386c9 ("ASoC: rsnd: call unregister for null_hw when removed")
Signed-off-by: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87r1hli215.wl-kuninori.morimoto.gx@renesas.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent b48e4aa4
...@@ -28,6 +28,7 @@ static struct rsnd_mod_ops adg_ops = { ...@@ -28,6 +28,7 @@ static struct rsnd_mod_ops adg_ops = {
struct rsnd_adg { struct rsnd_adg {
struct clk *clk[CLKMAX]; struct clk *clk[CLKMAX];
struct clk *clkout[CLKOUTMAX]; struct clk *clkout[CLKOUTMAX];
struct clk *null_clk;
struct clk_onecell_data onecell; struct clk_onecell_data onecell;
struct rsnd_mod mod; struct rsnd_mod mod;
int clk_rate[CLKMAX]; int clk_rate[CLKMAX];
...@@ -363,53 +364,52 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate) ...@@ -363,53 +364,52 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate)
void rsnd_adg_clk_control(struct rsnd_priv *priv, int enable) void rsnd_adg_clk_control(struct rsnd_priv *priv, int enable)
{ {
struct rsnd_adg *adg = rsnd_priv_to_adg(priv); struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
struct device *dev = rsnd_priv_to_dev(priv);
struct clk *clk; struct clk *clk;
int i; int i;
for_each_rsnd_clk(clk, adg, i) { for_each_rsnd_clk(clk, adg, i) {
if (enable) { if (enable) {
int ret = clk_prepare_enable(clk); clk_prepare_enable(clk);
/* /*
* We shouldn't use clk_get_rate() under * We shouldn't use clk_get_rate() under
* atomic context. Let's keep it when * atomic context. Let's keep it when
* rsnd_adg_clk_enable() was called * rsnd_adg_clk_enable() was called
*/ */
adg->clk_rate[i] = 0; adg->clk_rate[i] = clk_get_rate(clk);
if (ret < 0)
dev_warn(dev, "can't use clk %d\n", i);
else
adg->clk_rate[i] = clk_get_rate(clk);
} else { } else {
if (adg->clk_rate[i]) clk_disable_unprepare(clk);
clk_disable_unprepare(clk);
adg->clk_rate[i] = 0;
} }
} }
} }
#define NULL_CLK "rsnd_adg_null" static struct clk *rsnd_adg_create_null_clk(struct rsnd_priv *priv,
static struct clk *rsnd_adg_null_clk_get(struct rsnd_priv *priv) const char * const name,
const char *parent)
{ {
struct device *dev = rsnd_priv_to_dev(priv); struct device *dev = rsnd_priv_to_dev(priv);
struct clk *clk;
clk = clk_register_fixed_rate(dev, name, parent, 0, 0);
if (IS_ERR(clk)) {
dev_err(dev, "create null clk error\n");
return NULL;
}
if (!priv->null_hw) { return clk;
struct clk_hw *_hw; }
int ret;
_hw = clk_hw_register_fixed_rate_with_accuracy(dev, NULL_CLK, NULL, 0, 0, 0); static struct clk *rsnd_adg_null_clk_get(struct rsnd_priv *priv)
if (IS_ERR(_hw)) {
return NULL; struct rsnd_adg *adg = priv->adg;
ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_simple_get, _hw); if (!adg->null_clk) {
if (ret < 0) static const char * const name = "rsnd_adg_null";
clk_hw_unregister_fixed_rate(_hw);
priv->null_hw = _hw; adg->null_clk = rsnd_adg_create_null_clk(priv, name, NULL);
} }
return clk_hw_get_clk(priv->null_hw, NULL_CLK); return adg->null_clk;
} }
static void rsnd_adg_get_clkin(struct rsnd_priv *priv) static void rsnd_adg_get_clkin(struct rsnd_priv *priv)
...@@ -666,10 +666,12 @@ void rsnd_adg_remove(struct rsnd_priv *priv) ...@@ -666,10 +666,12 @@ void rsnd_adg_remove(struct rsnd_priv *priv)
for_each_rsnd_clkout(clk, adg, i) for_each_rsnd_clkout(clk, adg, i)
if (adg->clkout[i]) if (adg->clkout[i])
clk_unregister_fixed_rate(adg->clkout[i]); clk_unregister_fixed_rate(adg->clkout[i]);
if (priv->null_hw)
clk_hw_unregister_fixed_rate(priv->null_hw);
of_clk_del_provider(np); of_clk_del_provider(np);
rsnd_adg_clk_disable(priv); rsnd_adg_clk_disable(priv);
/* It should be called after rsnd_adg_clk_disable() */
if (adg->null_clk)
clk_unregister_fixed_rate(adg->null_clk);
} }
...@@ -646,7 +646,6 @@ struct rsnd_priv { ...@@ -646,7 +646,6 @@ struct rsnd_priv {
* below value will be filled on rsnd_adg_probe() * below value will be filled on rsnd_adg_probe()
*/ */
void *adg; void *adg;
struct clk_hw *null_hw;
/* /*
* below value will be filled on rsnd_dma_probe() * below value will be filled on rsnd_dma_probe()
......
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