All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
To: Mark Brown <broonie@kernel.org>
Cc: Linux-ALSA <alsa-devel@alsa-project.org>
Subject: [PATCH 4/5] ASoC: rsnd: adg: check return value for rsnd_adg_get_clkin/out()
Date: 02 Jun 2021 08:44:09 +0900	[thread overview]
Message-ID: <87pmx5i20m.wl-kuninori.morimoto.gx@renesas.com> (raw)
In-Reply-To: <87v96xi22i.wl-kuninori.morimoto.gx@renesas.com>

From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

Current rsnd_adg_get_clkin/out() are void function,
thus adg->clk/clkout[i] might be NULL.

But, for_each_rsnd_clk/clkout() macros are assuming
all clks are non NULL.

Because of this mismatch, code can be complex and/or buggy.
These functions return error by this patch,
and make sure all clks are non NULL.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 sound/soc/sh/rcar/adg.c | 84 ++++++++++++++++++++++++++++++-----------
 1 file changed, 61 insertions(+), 23 deletions(-)

diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index 3dfd07c8a7e3..0ebee1ed06a9 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -412,25 +412,53 @@ static struct clk *rsnd_adg_null_clk_get(struct rsnd_priv *priv)
 	return adg->null_clk;
 }
 
-static void rsnd_adg_get_clkin(struct rsnd_priv *priv)
+static void rsnd_adg_null_clk_clean(struct rsnd_priv *priv)
+{
+	struct rsnd_adg *adg = priv->adg;
+
+	if (adg->null_clk)
+		clk_unregister_fixed_rate(adg->null_clk);
+}
+
+static int rsnd_adg_get_clkin(struct rsnd_priv *priv)
 {
 	struct rsnd_adg *adg = priv->adg;
 	struct device *dev = rsnd_priv_to_dev(priv);
+	struct clk *clk;
 	int i;
 
 	for (i = 0; i < CLKMAX; i++) {
-		struct clk *clk = devm_clk_get(dev, clk_name[i]);
+		clk = devm_clk_get(dev, clk_name[i]);
 
 		if (IS_ERR(clk))
 			clk = rsnd_adg_null_clk_get(priv);
 		if (IS_ERR(clk))
-			dev_err(dev, "no adg clock (%s)\n", clk_name[i]);
+			goto err;
 
 		adg->clk[i] = clk;
 	}
+
+	return 0;
+
+err:
+	dev_err(dev, "adg clock IN get failed\n");
+
+	rsnd_adg_null_clk_clean(priv);
+
+	return -EIO;
+}
+
+static void rsnd_adg_unregister_clkout(struct rsnd_priv *priv)
+{
+	struct rsnd_adg *adg = priv->adg;
+	struct clk *clk;
+	int i;
+
+	for_each_rsnd_clkout(clk, adg, i)
+		clk_unregister_fixed_rate(clk);
 }
 
-static void rsnd_adg_get_clkout(struct rsnd_priv *priv)
+static int rsnd_adg_get_clkout(struct rsnd_priv *priv)
 {
 	struct rsnd_adg *adg = priv->adg;
 	struct clk *clk;
@@ -472,9 +500,8 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv)
 
 	req_size = prop->length / sizeof(u32);
 	if (req_size > REQ_SIZE) {
-		dev_err(dev,
-			"too many clock-frequency, use top %d\n", REQ_SIZE);
-		req_size = REQ_SIZE;
+		dev_err(dev, "too many clock-frequency\n");
+		return -EINVAL;
 	}
 
 	of_property_read_u32_array(np, "clock-frequency", req_rate, req_size);
@@ -555,10 +582,11 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv)
 	if (!count) {
 		clk = clk_register_fixed_rate(dev, clkout_name[CLKOUT],
 					      parent_clk_name, 0, req_rate[0]);
-		if (!IS_ERR(clk)) {
-			adg->clkout[CLKOUT] = clk;
-			of_clk_add_provider(np, of_clk_src_simple_get, clk);
-		}
+		if (IS_ERR(clk))
+			goto err;
+
+		adg->clkout[CLKOUT] = clk;
+		of_clk_add_provider(np, of_clk_src_simple_get, clk);
 	}
 	/*
 	 * for clkout0/1/2/3
@@ -568,8 +596,10 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv)
 			clk = clk_register_fixed_rate(dev, clkout_name[i],
 						      parent_clk_name, 0,
 						      req_rate[0]);
-			if (!IS_ERR(clk))
-				adg->clkout[i] = clk;
+			if (IS_ERR(clk))
+				goto err;
+
+			adg->clkout[i] = clk;
 		}
 		adg->onecell.clks	= adg->clkout;
 		adg->onecell.clk_num	= CLKOUTMAX;
@@ -581,6 +611,15 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv)
 	adg->ckr = ckr;
 	adg->rbga = rbga;
 	adg->rbgb = rbgb;
+
+	return 0;
+
+err:
+	dev_err(dev, "adg clock OUT get failed\n");
+
+	rsnd_adg_unregister_clkout(priv);
+
+	return -EIO;
 }
 
 #if defined(DEBUG) || defined(CONFIG_DEBUG_FS)
@@ -646,8 +685,13 @@ int rsnd_adg_probe(struct rsnd_priv *priv)
 
 	priv->adg = adg;
 
-	rsnd_adg_get_clkin(priv);
-	rsnd_adg_get_clkout(priv);
+	ret = rsnd_adg_get_clkin(priv);
+	if (ret)
+		return ret;
+
+	ret = rsnd_adg_get_clkout(priv);
+	if (ret)
+		return ret;
 
 	rsnd_adg_clk_enable(priv);
 	rsnd_adg_clk_dbg_info(priv, NULL);
@@ -659,19 +703,13 @@ void rsnd_adg_remove(struct rsnd_priv *priv)
 {
 	struct device *dev = rsnd_priv_to_dev(priv);
 	struct device_node *np = dev->of_node;
-	struct rsnd_adg *adg = priv->adg;
-	struct clk *clk;
-	int i;
 
-	for_each_rsnd_clkout(clk, adg, i)
-		if (adg->clkout[i])
-			clk_unregister_fixed_rate(adg->clkout[i]);
+	rsnd_adg_unregister_clkout(priv);
 
 	of_clk_del_provider(np);
 
 	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);
+	rsnd_adg_null_clk_clean(priv);
 }
-- 
2.25.1


  parent reply	other threads:[~2021-06-01 23:45 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-01 23:43 [PATCH 0/5] ASoC: rsnd: tidyup adg and header Kuninori Morimoto
2021-06-01 23:43 ` [PATCH 1/5] ASoC: rsnd: adg: supply __printf(x, y) formatting for dbg_msg() Kuninori Morimoto
2021-06-01 23:43 ` [PATCH 2/5] ASoC: rsnd: adg: tidyup rsnd_adg_get_clkin/out() parameter Kuninori Morimoto
2021-06-01 23:43 ` [PATCH 3/5] ASoC: rsnd: adg: use more simple method for null_clk Kuninori Morimoto
2021-06-01 23:44 ` Kuninori Morimoto [this message]
2021-06-01 23:44 ` [PATCH 5/5] ASoC: rsnd: tidyup __rsnd_mod_xxx macro comments Kuninori Morimoto
2021-06-03 18:41 ` [PATCH 0/5] ASoC: rsnd: tidyup adg and header Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87pmx5i20m.wl-kuninori.morimoto.gx@renesas.com \
    --to=kuninori.morimoto.gx@renesas.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.