linux-arm-msm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] ASoC: q6afe-clocks: fix reprobing of the driver
@ 2021-03-27  9:28 Dmitry Baryshkov
  2021-03-29 20:13 ` Stephen Boyd
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Dmitry Baryshkov @ 2021-03-27  9:28 UTC (permalink / raw)
  To: Srinivas Kandagatla, Banajit Goswami, Liam Girdwood, Mark Brown,
	linux-arm-msm, alsa-devel
  Cc: Jaroslav Kysela, Takashi Iwai, Bjorn Andersson, Andy Gross

Q6afe-clocks driver can get reprobed. For example if the APR services
are restarted after the firmware crash. However currently Q6afe-clocks
driver will oops because hw.init will get cleared during first _probe
call. Rewrite the driver to fill the clock data at runtime rather than
using big static array of clocks.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 sound/soc/qcom/qdsp6/q6afe-clocks.c | 209 ++++++++++++++--------------
 sound/soc/qcom/qdsp6/q6afe.c        |   2 +-
 sound/soc/qcom/qdsp6/q6afe.h        |   2 +-
 3 files changed, 108 insertions(+), 105 deletions(-)

diff --git a/sound/soc/qcom/qdsp6/q6afe-clocks.c b/sound/soc/qcom/qdsp6/q6afe-clocks.c
index f0362f061652..9431656283cd 100644
--- a/sound/soc/qcom/qdsp6/q6afe-clocks.c
+++ b/sound/soc/qcom/qdsp6/q6afe-clocks.c
@@ -11,33 +11,29 @@
 #include <linux/slab.h>
 #include "q6afe.h"
 
-#define Q6AFE_CLK(id) &(struct q6afe_clk) {		\
+#define Q6AFE_CLK(id) {					\
 		.clk_id	= id,				\
 		.afe_clk_id	= Q6AFE_##id,		\
 		.name = #id,				\
-		.attributes = LPASS_CLK_ATTRIBUTE_COUPLE_NO, \
 		.rate = 19200000,			\
-		.hw.init = &(struct clk_init_data) {	\
-			.ops = &clk_q6afe_ops,		\
-			.name = #id,			\
-		},					\
 	}
 
-#define Q6AFE_VOTE_CLK(id, blkid, n) &(struct q6afe_clk) { \
+#define Q6AFE_VOTE_CLK(id, blkid, n) {			\
 		.clk_id	= id,				\
 		.afe_clk_id = blkid,			\
-		.name = #n,				\
-		.hw.init = &(struct clk_init_data) {	\
-			.ops = &clk_vote_q6afe_ops,	\
-			.name = #id,			\
-		},					\
+		.name = n,				\
 	}
 
-struct q6afe_clk {
-	struct device *dev;
+struct q6afe_clk_init {
 	int clk_id;
 	int afe_clk_id;
 	char *name;
+	int rate;
+};
+
+struct q6afe_clk {
+	struct device *dev;
+	int afe_clk_id;
 	int attributes;
 	int rate;
 	uint32_t handle;
@@ -48,8 +44,7 @@ struct q6afe_clk {
 
 struct q6afe_cc {
 	struct device *dev;
-	struct q6afe_clk **clks;
-	int num_clks;
+	struct q6afe_clk *clks[Q6AFE_MAX_CLK_ID];
 };
 
 static int clk_q6afe_prepare(struct clk_hw *hw)
@@ -105,7 +100,7 @@ static int clk_vote_q6afe_block(struct clk_hw *hw)
 	struct q6afe_clk *clk = to_q6afe_clk(hw);
 
 	return q6afe_vote_lpass_core_hw(clk->dev, clk->afe_clk_id,
-					clk->name, &clk->handle);
+					clk_hw_get_name(&clk->hw), &clk->handle);
 }
 
 static void clk_unvote_q6afe_block(struct clk_hw *hw)
@@ -120,84 +115,76 @@ static const struct clk_ops clk_vote_q6afe_ops = {
 	.unprepare	= clk_unvote_q6afe_block,
 };
 
-static struct q6afe_clk *q6afe_clks[Q6AFE_MAX_CLK_ID] = {
-	[LPASS_CLK_ID_PRI_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_PRI_MI2S_IBIT),
-	[LPASS_CLK_ID_PRI_MI2S_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_PRI_MI2S_EBIT),
-	[LPASS_CLK_ID_SEC_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEC_MI2S_IBIT),
-	[LPASS_CLK_ID_SEC_MI2S_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEC_MI2S_EBIT),
-	[LPASS_CLK_ID_TER_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_TER_MI2S_IBIT),
-	[LPASS_CLK_ID_TER_MI2S_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_TER_MI2S_EBIT),
-	[LPASS_CLK_ID_QUAD_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUAD_MI2S_IBIT),
-	[LPASS_CLK_ID_QUAD_MI2S_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUAD_MI2S_EBIT),
-	[LPASS_CLK_ID_SPEAKER_I2S_IBIT] =
-				Q6AFE_CLK(LPASS_CLK_ID_SPEAKER_I2S_IBIT),
-	[LPASS_CLK_ID_SPEAKER_I2S_EBIT] =
-				Q6AFE_CLK(LPASS_CLK_ID_SPEAKER_I2S_EBIT),
-	[LPASS_CLK_ID_SPEAKER_I2S_OSR] =
-				Q6AFE_CLK(LPASS_CLK_ID_SPEAKER_I2S_OSR),
-	[LPASS_CLK_ID_QUI_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUI_MI2S_IBIT),
-	[LPASS_CLK_ID_QUI_MI2S_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUI_MI2S_EBIT),
-	[LPASS_CLK_ID_SEN_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEN_MI2S_IBIT),
-	[LPASS_CLK_ID_SEN_MI2S_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEN_MI2S_EBIT),
-	[LPASS_CLK_ID_INT0_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT0_MI2S_IBIT),
-	[LPASS_CLK_ID_INT1_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT1_MI2S_IBIT),
-	[LPASS_CLK_ID_INT2_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT2_MI2S_IBIT),
-	[LPASS_CLK_ID_INT3_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT3_MI2S_IBIT),
-	[LPASS_CLK_ID_INT4_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT4_MI2S_IBIT),
-	[LPASS_CLK_ID_INT5_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT5_MI2S_IBIT),
-	[LPASS_CLK_ID_INT6_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT6_MI2S_IBIT),
-	[LPASS_CLK_ID_QUI_MI2S_OSR] = Q6AFE_CLK(LPASS_CLK_ID_QUI_MI2S_OSR),
-	[LPASS_CLK_ID_PRI_PCM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_PRI_PCM_IBIT),
-	[LPASS_CLK_ID_PRI_PCM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_PRI_PCM_EBIT),
-	[LPASS_CLK_ID_SEC_PCM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEC_PCM_IBIT),
-	[LPASS_CLK_ID_SEC_PCM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEC_PCM_EBIT),
-	[LPASS_CLK_ID_TER_PCM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_TER_PCM_IBIT),
-	[LPASS_CLK_ID_TER_PCM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_TER_PCM_EBIT),
-	[LPASS_CLK_ID_QUAD_PCM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUAD_PCM_IBIT),
-	[LPASS_CLK_ID_QUAD_PCM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUAD_PCM_EBIT),
-	[LPASS_CLK_ID_QUIN_PCM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUIN_PCM_IBIT),
-	[LPASS_CLK_ID_QUIN_PCM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUIN_PCM_EBIT),
-	[LPASS_CLK_ID_QUI_PCM_OSR] = Q6AFE_CLK(LPASS_CLK_ID_QUI_PCM_OSR),
-	[LPASS_CLK_ID_PRI_TDM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_PRI_TDM_IBIT),
-	[LPASS_CLK_ID_PRI_TDM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_PRI_TDM_EBIT),
-	[LPASS_CLK_ID_SEC_TDM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEC_TDM_IBIT),
-	[LPASS_CLK_ID_SEC_TDM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEC_TDM_EBIT),
-	[LPASS_CLK_ID_TER_TDM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_TER_TDM_IBIT),
-	[LPASS_CLK_ID_TER_TDM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_TER_TDM_EBIT),
-	[LPASS_CLK_ID_QUAD_TDM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUAD_TDM_IBIT),
-	[LPASS_CLK_ID_QUAD_TDM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUAD_TDM_EBIT),
-	[LPASS_CLK_ID_QUIN_TDM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUIN_TDM_IBIT),
-	[LPASS_CLK_ID_QUIN_TDM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUIN_TDM_EBIT),
-	[LPASS_CLK_ID_QUIN_TDM_OSR] = Q6AFE_CLK(LPASS_CLK_ID_QUIN_TDM_OSR),
-	[LPASS_CLK_ID_MCLK_1] = Q6AFE_CLK(LPASS_CLK_ID_MCLK_1),
-	[LPASS_CLK_ID_MCLK_2] = Q6AFE_CLK(LPASS_CLK_ID_MCLK_2),
-	[LPASS_CLK_ID_MCLK_3] = Q6AFE_CLK(LPASS_CLK_ID_MCLK_3),
-	[LPASS_CLK_ID_MCLK_4] = Q6AFE_CLK(LPASS_CLK_ID_MCLK_4),
-	[LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE] =
-		Q6AFE_CLK(LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE),
-	[LPASS_CLK_ID_INT_MCLK_0] = Q6AFE_CLK(LPASS_CLK_ID_INT_MCLK_0),
-	[LPASS_CLK_ID_INT_MCLK_1] = Q6AFE_CLK(LPASS_CLK_ID_INT_MCLK_1),
-	[LPASS_CLK_ID_WSA_CORE_MCLK] = Q6AFE_CLK(LPASS_CLK_ID_WSA_CORE_MCLK),
-	[LPASS_CLK_ID_WSA_CORE_NPL_MCLK] =
-				Q6AFE_CLK(LPASS_CLK_ID_WSA_CORE_NPL_MCLK),
-	[LPASS_CLK_ID_VA_CORE_MCLK] = Q6AFE_CLK(LPASS_CLK_ID_VA_CORE_MCLK),
-	[LPASS_CLK_ID_TX_CORE_MCLK] = Q6AFE_CLK(LPASS_CLK_ID_TX_CORE_MCLK),
-	[LPASS_CLK_ID_TX_CORE_NPL_MCLK] =
-			Q6AFE_CLK(LPASS_CLK_ID_TX_CORE_NPL_MCLK),
-	[LPASS_CLK_ID_RX_CORE_MCLK] = Q6AFE_CLK(LPASS_CLK_ID_RX_CORE_MCLK),
-	[LPASS_CLK_ID_RX_CORE_NPL_MCLK] =
-				Q6AFE_CLK(LPASS_CLK_ID_RX_CORE_NPL_MCLK),
-	[LPASS_CLK_ID_VA_CORE_2X_MCLK] =
-				Q6AFE_CLK(LPASS_CLK_ID_VA_CORE_2X_MCLK),
-	[LPASS_HW_AVTIMER_VOTE] = Q6AFE_VOTE_CLK(LPASS_HW_AVTIMER_VOTE,
-						 Q6AFE_LPASS_CORE_AVTIMER_BLOCK,
-						 "LPASS_AVTIMER_MACRO"),
-	[LPASS_HW_MACRO_VOTE] = Q6AFE_VOTE_CLK(LPASS_HW_MACRO_VOTE,
-						Q6AFE_LPASS_CORE_HW_MACRO_BLOCK,
-						"LPASS_HW_MACRO"),
-	[LPASS_HW_DCODEC_VOTE] = Q6AFE_VOTE_CLK(LPASS_HW_DCODEC_VOTE,
-					Q6AFE_LPASS_CORE_HW_DCODEC_BLOCK,
-					"LPASS_HW_DCODEC"),
+static const struct q6afe_clk_init q6afe_clks[] = {
+	Q6AFE_CLK(LPASS_CLK_ID_PRI_MI2S_IBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_PRI_MI2S_EBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_SEC_MI2S_IBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_SEC_MI2S_EBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_TER_MI2S_IBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_TER_MI2S_EBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_QUAD_MI2S_IBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_QUAD_MI2S_EBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_SPEAKER_I2S_IBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_SPEAKER_I2S_EBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_SPEAKER_I2S_OSR),
+	Q6AFE_CLK(LPASS_CLK_ID_QUI_MI2S_IBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_QUI_MI2S_EBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_SEN_MI2S_IBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_SEN_MI2S_EBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_INT0_MI2S_IBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_INT1_MI2S_IBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_INT2_MI2S_IBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_INT3_MI2S_IBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_INT4_MI2S_IBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_INT5_MI2S_IBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_INT6_MI2S_IBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_QUI_MI2S_OSR),
+	Q6AFE_CLK(LPASS_CLK_ID_PRI_PCM_IBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_PRI_PCM_EBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_SEC_PCM_IBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_SEC_PCM_EBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_TER_PCM_IBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_TER_PCM_EBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_QUAD_PCM_IBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_QUAD_PCM_EBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_QUIN_PCM_IBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_QUIN_PCM_EBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_QUI_PCM_OSR),
+	Q6AFE_CLK(LPASS_CLK_ID_PRI_TDM_IBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_PRI_TDM_EBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_SEC_TDM_IBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_SEC_TDM_EBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_TER_TDM_IBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_TER_TDM_EBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_QUAD_TDM_IBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_QUAD_TDM_EBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_QUIN_TDM_IBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_QUIN_TDM_EBIT),
+	Q6AFE_CLK(LPASS_CLK_ID_QUIN_TDM_OSR),
+	Q6AFE_CLK(LPASS_CLK_ID_MCLK_1),
+	Q6AFE_CLK(LPASS_CLK_ID_MCLK_2),
+	Q6AFE_CLK(LPASS_CLK_ID_MCLK_3),
+	Q6AFE_CLK(LPASS_CLK_ID_MCLK_4),
+	Q6AFE_CLK(LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE),
+	Q6AFE_CLK(LPASS_CLK_ID_INT_MCLK_0),
+	Q6AFE_CLK(LPASS_CLK_ID_INT_MCLK_1),
+	Q6AFE_CLK(LPASS_CLK_ID_WSA_CORE_MCLK),
+	Q6AFE_CLK(LPASS_CLK_ID_WSA_CORE_NPL_MCLK),
+	Q6AFE_CLK(LPASS_CLK_ID_VA_CORE_MCLK),
+	Q6AFE_CLK(LPASS_CLK_ID_TX_CORE_MCLK),
+	Q6AFE_CLK(LPASS_CLK_ID_TX_CORE_NPL_MCLK),
+	Q6AFE_CLK(LPASS_CLK_ID_RX_CORE_MCLK),
+	Q6AFE_CLK(LPASS_CLK_ID_RX_CORE_NPL_MCLK),
+	Q6AFE_CLK(LPASS_CLK_ID_VA_CORE_2X_MCLK),
+	Q6AFE_VOTE_CLK(LPASS_HW_AVTIMER_VOTE,
+		       Q6AFE_LPASS_CORE_AVTIMER_BLOCK,
+		       "LPASS_AVTIMER_MACRO"),
+	Q6AFE_VOTE_CLK(LPASS_HW_MACRO_VOTE,
+		       Q6AFE_LPASS_CORE_HW_MACRO_BLOCK,
+		       "LPASS_HW_MACRO"),
+	Q6AFE_VOTE_CLK(LPASS_HW_DCODEC_VOTE,
+		       Q6AFE_LPASS_CORE_HW_DCODEC_BLOCK,
+		       "LPASS_HW_DCODEC"),
 };
 
 static struct clk_hw *q6afe_of_clk_hw_get(struct of_phandle_args *clkspec,
@@ -207,7 +194,7 @@ static struct clk_hw *q6afe_of_clk_hw_get(struct of_phandle_args *clkspec,
 	unsigned int idx = clkspec->args[0];
 	unsigned int attr = clkspec->args[1];
 
-	if (idx >= cc->num_clks || attr > LPASS_CLK_ATTRIBUTE_COUPLE_DIVISOR) {
+	if (idx >= Q6AFE_MAX_CLK_ID || attr > LPASS_CLK_ATTRIBUTE_COUPLE_DIVISOR) {
 		dev_err(cc->dev, "Invalid clk specifier (%d, %d)\n", idx, attr);
 		return ERR_PTR(-EINVAL);
 	}
@@ -230,20 +217,36 @@ static int q6afe_clock_dev_probe(struct platform_device *pdev)
 	if (!cc)
 		return -ENOMEM;
 
-	cc->clks = &q6afe_clks[0];
-	cc->num_clks = ARRAY_SIZE(q6afe_clks);
+	cc->dev = dev;
 	for (i = 0; i < ARRAY_SIZE(q6afe_clks); i++) {
-		if (!q6afe_clks[i])
-			continue;
+		unsigned int id = q6afe_clks[i].clk_id;
+		struct clk_init_data init = {
+			.name =  q6afe_clks[i].name,
+		};
+		struct q6afe_clk *clk;
+
+		clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL);
+		if (!clk)
+			return -ENOMEM;
+
+		clk->dev = dev;
+		clk->afe_clk_id = q6afe_clks[i].afe_clk_id;
+		clk->rate = q6afe_clks[i].rate;
+		clk->hw.init = &init;
+
+		if (clk->rate)
+			init.ops = &clk_q6afe_ops;
+		else
+			init.ops = &clk_vote_q6afe_ops;
 
-		q6afe_clks[i]->dev = dev;
+		cc->clks[id] = clk;
 
-		ret = devm_clk_hw_register(dev, &q6afe_clks[i]->hw);
+		ret = devm_clk_hw_register(dev, &clk->hw);
 		if (ret)
 			return ret;
 	}
 
-	ret = of_clk_add_hw_provider(dev->of_node, q6afe_of_clk_hw_get, cc);
+	ret = devm_of_clk_add_hw_provider(dev, q6afe_of_clk_hw_get, cc);
 	if (ret)
 		return ret;
 
diff --git a/sound/soc/qcom/qdsp6/q6afe.c b/sound/soc/qcom/qdsp6/q6afe.c
index cad1cd1bfdf0..4327b72162ec 100644
--- a/sound/soc/qcom/qdsp6/q6afe.c
+++ b/sound/soc/qcom/qdsp6/q6afe.c
@@ -1681,7 +1681,7 @@ int q6afe_unvote_lpass_core_hw(struct device *dev, uint32_t hw_block_id,
 EXPORT_SYMBOL(q6afe_unvote_lpass_core_hw);
 
 int q6afe_vote_lpass_core_hw(struct device *dev, uint32_t hw_block_id,
-			     char *client_name, uint32_t *client_handle)
+			     const char *client_name, uint32_t *client_handle)
 {
 	struct q6afe *afe = dev_get_drvdata(dev->parent);
 	struct afe_cmd_remote_lpass_core_hw_vote_request *vote_cfg;
diff --git a/sound/soc/qcom/qdsp6/q6afe.h b/sound/soc/qcom/qdsp6/q6afe.h
index 22e10269aa10..3845b56c0ed3 100644
--- a/sound/soc/qcom/qdsp6/q6afe.h
+++ b/sound/soc/qcom/qdsp6/q6afe.h
@@ -236,7 +236,7 @@ int q6afe_port_set_sysclk(struct q6afe_port *port, int clk_id,
 int q6afe_set_lpass_clock(struct device *dev, int clk_id, int clk_src,
 			  int clk_root, unsigned int freq);
 int q6afe_vote_lpass_core_hw(struct device *dev, uint32_t hw_block_id,
-			     char *client_name, uint32_t *client_handle);
+			     const char *client_name, uint32_t *client_handle);
 int q6afe_unvote_lpass_core_hw(struct device *dev, uint32_t hw_block_id,
 			       uint32_t client_handle);
 #endif /* __Q6AFE_H__ */
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] ASoC: q6afe-clocks: fix reprobing of the driver
  2021-03-27  9:28 [PATCH] ASoC: q6afe-clocks: fix reprobing of the driver Dmitry Baryshkov
@ 2021-03-29 20:13 ` Stephen Boyd
  2021-03-29 21:26   ` Dmitry Baryshkov
  2021-03-30  9:08 ` Srinivas Kandagatla
  2021-03-30 16:05 ` Mark Brown
  2 siblings, 1 reply; 5+ messages in thread
From: Stephen Boyd @ 2021-03-29 20:13 UTC (permalink / raw)
  To: Banajit Goswami, Dmitry Baryshkov, Liam Girdwood, Mark Brown,
	Srinivas Kandagatla, alsa-devel, linux-arm-msm
  Cc: Jaroslav Kysela, Takashi Iwai, Bjorn Andersson, Andy Gross

Quoting Dmitry Baryshkov (2021-03-27 02:28:57)
> Q6afe-clocks driver can get reprobed. For example if the APR services
> are restarted after the firmware crash. However currently Q6afe-clocks
> driver will oops because hw.init will get cleared during first _probe
> call. Rewrite the driver to fill the clock data at runtime rather than
> using big static array of clocks.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

Any fixes tag?

> ---

Reviewed-by: Stephen Boyd <sboyd@kernel.org>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] ASoC: q6afe-clocks: fix reprobing of the driver
  2021-03-29 20:13 ` Stephen Boyd
@ 2021-03-29 21:26   ` Dmitry Baryshkov
  0 siblings, 0 replies; 5+ messages in thread
From: Dmitry Baryshkov @ 2021-03-29 21:26 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Banajit Goswami, Liam Girdwood, Mark Brown, Srinivas Kandagatla,
	alsa-devel, open list:DRM DRIVER FOR MSM ADRENO GPU,
	Jaroslav Kysela, Takashi Iwai, Bjorn Andersson, Andy Gross

On Mon, 29 Mar 2021 at 23:13, Stephen Boyd <sboyd@kernel.org> wrote:
>
> Quoting Dmitry Baryshkov (2021-03-27 02:28:57)
> > Q6afe-clocks driver can get reprobed. For example if the APR services
> > are restarted after the firmware crash. However currently Q6afe-clocks
> > driver will oops because hw.init will get cleared during first _probe
> > call. Rewrite the driver to fill the clock data at runtime rather than
> > using big static array of clocks.
> >
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>
> Any fixes tag?

Missed that.
Fixes: 520a1c396d19 ("ASoC: q6afe-clocks: add q6afe clock controller")


-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] ASoC: q6afe-clocks: fix reprobing of the driver
  2021-03-27  9:28 [PATCH] ASoC: q6afe-clocks: fix reprobing of the driver Dmitry Baryshkov
  2021-03-29 20:13 ` Stephen Boyd
@ 2021-03-30  9:08 ` Srinivas Kandagatla
  2021-03-30 16:05 ` Mark Brown
  2 siblings, 0 replies; 5+ messages in thread
From: Srinivas Kandagatla @ 2021-03-30  9:08 UTC (permalink / raw)
  To: Dmitry Baryshkov, Banajit Goswami, Liam Girdwood, Mark Brown,
	linux-arm-msm, alsa-devel
  Cc: Jaroslav Kysela, Takashi Iwai, Bjorn Andersson, Andy Gross

Thanks Dmitry for looking at this,

On 27/03/2021 09:28, Dmitry Baryshkov wrote:
> Q6afe-clocks driver can get reprobed. For example if the APR services
> are restarted after the firmware crash. However currently Q6afe-clocks
> driver will oops because hw.init will get cleared during first _probe
> call. Rewrite the driver to fill the clock data at runtime rather than
> using big static array of clocks.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---

Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>


--srini

>   sound/soc/qcom/qdsp6/q6afe-clocks.c | 209 ++++++++++++++--------------
>   sound/soc/qcom/qdsp6/q6afe.c        |   2 +-
>   sound/soc/qcom/qdsp6/q6afe.h        |   2 +-
>   3 files changed, 108 insertions(+), 105 deletions(-)
> 
> diff --git a/sound/soc/qcom/qdsp6/q6afe-clocks.c b/sound/soc/qcom/qdsp6/q6afe-clocks.c
> index f0362f061652..9431656283cd 100644
> --- a/sound/soc/qcom/qdsp6/q6afe-clocks.c
> +++ b/sound/soc/qcom/qdsp6/q6afe-clocks.c
> @@ -11,33 +11,29 @@
>   #include <linux/slab.h>
>   #include "q6afe.h"
>   
> -#define Q6AFE_CLK(id) &(struct q6afe_clk) {		\
> +#define Q6AFE_CLK(id) {					\
>   		.clk_id	= id,				\
>   		.afe_clk_id	= Q6AFE_##id,		\
>   		.name = #id,				\
> -		.attributes = LPASS_CLK_ATTRIBUTE_COUPLE_NO, \
>   		.rate = 19200000,			\
> -		.hw.init = &(struct clk_init_data) {	\
> -			.ops = &clk_q6afe_ops,		\
> -			.name = #id,			\
> -		},					\
>   	}
>   
> -#define Q6AFE_VOTE_CLK(id, blkid, n) &(struct q6afe_clk) { \
> +#define Q6AFE_VOTE_CLK(id, blkid, n) {			\
>   		.clk_id	= id,				\
>   		.afe_clk_id = blkid,			\
> -		.name = #n,				\
> -		.hw.init = &(struct clk_init_data) {	\
> -			.ops = &clk_vote_q6afe_ops,	\
> -			.name = #id,			\
> -		},					\
> +		.name = n,				\
>   	}
>   
> -struct q6afe_clk {
> -	struct device *dev;
> +struct q6afe_clk_init {
>   	int clk_id;
>   	int afe_clk_id;
>   	char *name;
> +	int rate;
> +};
> +
> +struct q6afe_clk {
> +	struct device *dev;
> +	int afe_clk_id;
>   	int attributes;
>   	int rate;
>   	uint32_t handle;
> @@ -48,8 +44,7 @@ struct q6afe_clk {
>   
>   struct q6afe_cc {
>   	struct device *dev;
> -	struct q6afe_clk **clks;
> -	int num_clks;
> +	struct q6afe_clk *clks[Q6AFE_MAX_CLK_ID];
>   };
>   
>   static int clk_q6afe_prepare(struct clk_hw *hw)
> @@ -105,7 +100,7 @@ static int clk_vote_q6afe_block(struct clk_hw *hw)
>   	struct q6afe_clk *clk = to_q6afe_clk(hw);
>   
>   	return q6afe_vote_lpass_core_hw(clk->dev, clk->afe_clk_id,
> -					clk->name, &clk->handle);
> +					clk_hw_get_name(&clk->hw), &clk->handle);
>   }
>   
>   static void clk_unvote_q6afe_block(struct clk_hw *hw)
> @@ -120,84 +115,76 @@ static const struct clk_ops clk_vote_q6afe_ops = {
>   	.unprepare	= clk_unvote_q6afe_block,
>   };
>   
> -static struct q6afe_clk *q6afe_clks[Q6AFE_MAX_CLK_ID] = {
> -	[LPASS_CLK_ID_PRI_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_PRI_MI2S_IBIT),
> -	[LPASS_CLK_ID_PRI_MI2S_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_PRI_MI2S_EBIT),
> -	[LPASS_CLK_ID_SEC_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEC_MI2S_IBIT),
> -	[LPASS_CLK_ID_SEC_MI2S_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEC_MI2S_EBIT),
> -	[LPASS_CLK_ID_TER_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_TER_MI2S_IBIT),
> -	[LPASS_CLK_ID_TER_MI2S_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_TER_MI2S_EBIT),
> -	[LPASS_CLK_ID_QUAD_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUAD_MI2S_IBIT),
> -	[LPASS_CLK_ID_QUAD_MI2S_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUAD_MI2S_EBIT),
> -	[LPASS_CLK_ID_SPEAKER_I2S_IBIT] =
> -				Q6AFE_CLK(LPASS_CLK_ID_SPEAKER_I2S_IBIT),
> -	[LPASS_CLK_ID_SPEAKER_I2S_EBIT] =
> -				Q6AFE_CLK(LPASS_CLK_ID_SPEAKER_I2S_EBIT),
> -	[LPASS_CLK_ID_SPEAKER_I2S_OSR] =
> -				Q6AFE_CLK(LPASS_CLK_ID_SPEAKER_I2S_OSR),
> -	[LPASS_CLK_ID_QUI_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUI_MI2S_IBIT),
> -	[LPASS_CLK_ID_QUI_MI2S_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUI_MI2S_EBIT),
> -	[LPASS_CLK_ID_SEN_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEN_MI2S_IBIT),
> -	[LPASS_CLK_ID_SEN_MI2S_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEN_MI2S_EBIT),
> -	[LPASS_CLK_ID_INT0_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT0_MI2S_IBIT),
> -	[LPASS_CLK_ID_INT1_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT1_MI2S_IBIT),
> -	[LPASS_CLK_ID_INT2_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT2_MI2S_IBIT),
> -	[LPASS_CLK_ID_INT3_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT3_MI2S_IBIT),
> -	[LPASS_CLK_ID_INT4_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT4_MI2S_IBIT),
> -	[LPASS_CLK_ID_INT5_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT5_MI2S_IBIT),
> -	[LPASS_CLK_ID_INT6_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT6_MI2S_IBIT),
> -	[LPASS_CLK_ID_QUI_MI2S_OSR] = Q6AFE_CLK(LPASS_CLK_ID_QUI_MI2S_OSR),
> -	[LPASS_CLK_ID_PRI_PCM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_PRI_PCM_IBIT),
> -	[LPASS_CLK_ID_PRI_PCM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_PRI_PCM_EBIT),
> -	[LPASS_CLK_ID_SEC_PCM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEC_PCM_IBIT),
> -	[LPASS_CLK_ID_SEC_PCM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEC_PCM_EBIT),
> -	[LPASS_CLK_ID_TER_PCM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_TER_PCM_IBIT),
> -	[LPASS_CLK_ID_TER_PCM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_TER_PCM_EBIT),
> -	[LPASS_CLK_ID_QUAD_PCM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUAD_PCM_IBIT),
> -	[LPASS_CLK_ID_QUAD_PCM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUAD_PCM_EBIT),
> -	[LPASS_CLK_ID_QUIN_PCM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUIN_PCM_IBIT),
> -	[LPASS_CLK_ID_QUIN_PCM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUIN_PCM_EBIT),
> -	[LPASS_CLK_ID_QUI_PCM_OSR] = Q6AFE_CLK(LPASS_CLK_ID_QUI_PCM_OSR),
> -	[LPASS_CLK_ID_PRI_TDM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_PRI_TDM_IBIT),
> -	[LPASS_CLK_ID_PRI_TDM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_PRI_TDM_EBIT),
> -	[LPASS_CLK_ID_SEC_TDM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEC_TDM_IBIT),
> -	[LPASS_CLK_ID_SEC_TDM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEC_TDM_EBIT),
> -	[LPASS_CLK_ID_TER_TDM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_TER_TDM_IBIT),
> -	[LPASS_CLK_ID_TER_TDM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_TER_TDM_EBIT),
> -	[LPASS_CLK_ID_QUAD_TDM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUAD_TDM_IBIT),
> -	[LPASS_CLK_ID_QUAD_TDM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUAD_TDM_EBIT),
> -	[LPASS_CLK_ID_QUIN_TDM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUIN_TDM_IBIT),
> -	[LPASS_CLK_ID_QUIN_TDM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUIN_TDM_EBIT),
> -	[LPASS_CLK_ID_QUIN_TDM_OSR] = Q6AFE_CLK(LPASS_CLK_ID_QUIN_TDM_OSR),
> -	[LPASS_CLK_ID_MCLK_1] = Q6AFE_CLK(LPASS_CLK_ID_MCLK_1),
> -	[LPASS_CLK_ID_MCLK_2] = Q6AFE_CLK(LPASS_CLK_ID_MCLK_2),
> -	[LPASS_CLK_ID_MCLK_3] = Q6AFE_CLK(LPASS_CLK_ID_MCLK_3),
> -	[LPASS_CLK_ID_MCLK_4] = Q6AFE_CLK(LPASS_CLK_ID_MCLK_4),
> -	[LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE] =
> -		Q6AFE_CLK(LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE),
> -	[LPASS_CLK_ID_INT_MCLK_0] = Q6AFE_CLK(LPASS_CLK_ID_INT_MCLK_0),
> -	[LPASS_CLK_ID_INT_MCLK_1] = Q6AFE_CLK(LPASS_CLK_ID_INT_MCLK_1),
> -	[LPASS_CLK_ID_WSA_CORE_MCLK] = Q6AFE_CLK(LPASS_CLK_ID_WSA_CORE_MCLK),
> -	[LPASS_CLK_ID_WSA_CORE_NPL_MCLK] =
> -				Q6AFE_CLK(LPASS_CLK_ID_WSA_CORE_NPL_MCLK),
> -	[LPASS_CLK_ID_VA_CORE_MCLK] = Q6AFE_CLK(LPASS_CLK_ID_VA_CORE_MCLK),
> -	[LPASS_CLK_ID_TX_CORE_MCLK] = Q6AFE_CLK(LPASS_CLK_ID_TX_CORE_MCLK),
> -	[LPASS_CLK_ID_TX_CORE_NPL_MCLK] =
> -			Q6AFE_CLK(LPASS_CLK_ID_TX_CORE_NPL_MCLK),
> -	[LPASS_CLK_ID_RX_CORE_MCLK] = Q6AFE_CLK(LPASS_CLK_ID_RX_CORE_MCLK),
> -	[LPASS_CLK_ID_RX_CORE_NPL_MCLK] =
> -				Q6AFE_CLK(LPASS_CLK_ID_RX_CORE_NPL_MCLK),
> -	[LPASS_CLK_ID_VA_CORE_2X_MCLK] =
> -				Q6AFE_CLK(LPASS_CLK_ID_VA_CORE_2X_MCLK),
> -	[LPASS_HW_AVTIMER_VOTE] = Q6AFE_VOTE_CLK(LPASS_HW_AVTIMER_VOTE,
> -						 Q6AFE_LPASS_CORE_AVTIMER_BLOCK,
> -						 "LPASS_AVTIMER_MACRO"),
> -	[LPASS_HW_MACRO_VOTE] = Q6AFE_VOTE_CLK(LPASS_HW_MACRO_VOTE,
> -						Q6AFE_LPASS_CORE_HW_MACRO_BLOCK,
> -						"LPASS_HW_MACRO"),
> -	[LPASS_HW_DCODEC_VOTE] = Q6AFE_VOTE_CLK(LPASS_HW_DCODEC_VOTE,
> -					Q6AFE_LPASS_CORE_HW_DCODEC_BLOCK,
> -					"LPASS_HW_DCODEC"),
> +static const struct q6afe_clk_init q6afe_clks[] = {
> +	Q6AFE_CLK(LPASS_CLK_ID_PRI_MI2S_IBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_PRI_MI2S_EBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_SEC_MI2S_IBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_SEC_MI2S_EBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_TER_MI2S_IBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_TER_MI2S_EBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_QUAD_MI2S_IBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_QUAD_MI2S_EBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_SPEAKER_I2S_IBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_SPEAKER_I2S_EBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_SPEAKER_I2S_OSR),
> +	Q6AFE_CLK(LPASS_CLK_ID_QUI_MI2S_IBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_QUI_MI2S_EBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_SEN_MI2S_IBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_SEN_MI2S_EBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_INT0_MI2S_IBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_INT1_MI2S_IBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_INT2_MI2S_IBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_INT3_MI2S_IBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_INT4_MI2S_IBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_INT5_MI2S_IBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_INT6_MI2S_IBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_QUI_MI2S_OSR),
> +	Q6AFE_CLK(LPASS_CLK_ID_PRI_PCM_IBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_PRI_PCM_EBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_SEC_PCM_IBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_SEC_PCM_EBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_TER_PCM_IBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_TER_PCM_EBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_QUAD_PCM_IBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_QUAD_PCM_EBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_QUIN_PCM_IBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_QUIN_PCM_EBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_QUI_PCM_OSR),
> +	Q6AFE_CLK(LPASS_CLK_ID_PRI_TDM_IBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_PRI_TDM_EBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_SEC_TDM_IBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_SEC_TDM_EBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_TER_TDM_IBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_TER_TDM_EBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_QUAD_TDM_IBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_QUAD_TDM_EBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_QUIN_TDM_IBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_QUIN_TDM_EBIT),
> +	Q6AFE_CLK(LPASS_CLK_ID_QUIN_TDM_OSR),
> +	Q6AFE_CLK(LPASS_CLK_ID_MCLK_1),
> +	Q6AFE_CLK(LPASS_CLK_ID_MCLK_2),
> +	Q6AFE_CLK(LPASS_CLK_ID_MCLK_3),
> +	Q6AFE_CLK(LPASS_CLK_ID_MCLK_4),
> +	Q6AFE_CLK(LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE),
> +	Q6AFE_CLK(LPASS_CLK_ID_INT_MCLK_0),
> +	Q6AFE_CLK(LPASS_CLK_ID_INT_MCLK_1),
> +	Q6AFE_CLK(LPASS_CLK_ID_WSA_CORE_MCLK),
> +	Q6AFE_CLK(LPASS_CLK_ID_WSA_CORE_NPL_MCLK),
> +	Q6AFE_CLK(LPASS_CLK_ID_VA_CORE_MCLK),
> +	Q6AFE_CLK(LPASS_CLK_ID_TX_CORE_MCLK),
> +	Q6AFE_CLK(LPASS_CLK_ID_TX_CORE_NPL_MCLK),
> +	Q6AFE_CLK(LPASS_CLK_ID_RX_CORE_MCLK),
> +	Q6AFE_CLK(LPASS_CLK_ID_RX_CORE_NPL_MCLK),
> +	Q6AFE_CLK(LPASS_CLK_ID_VA_CORE_2X_MCLK),
> +	Q6AFE_VOTE_CLK(LPASS_HW_AVTIMER_VOTE,
> +		       Q6AFE_LPASS_CORE_AVTIMER_BLOCK,
> +		       "LPASS_AVTIMER_MACRO"),
> +	Q6AFE_VOTE_CLK(LPASS_HW_MACRO_VOTE,
> +		       Q6AFE_LPASS_CORE_HW_MACRO_BLOCK,
> +		       "LPASS_HW_MACRO"),
> +	Q6AFE_VOTE_CLK(LPASS_HW_DCODEC_VOTE,
> +		       Q6AFE_LPASS_CORE_HW_DCODEC_BLOCK,
> +		       "LPASS_HW_DCODEC"),
>   };
>   
>   static struct clk_hw *q6afe_of_clk_hw_get(struct of_phandle_args *clkspec,
> @@ -207,7 +194,7 @@ static struct clk_hw *q6afe_of_clk_hw_get(struct of_phandle_args *clkspec,
>   	unsigned int idx = clkspec->args[0];
>   	unsigned int attr = clkspec->args[1];
>   
> -	if (idx >= cc->num_clks || attr > LPASS_CLK_ATTRIBUTE_COUPLE_DIVISOR) {
> +	if (idx >= Q6AFE_MAX_CLK_ID || attr > LPASS_CLK_ATTRIBUTE_COUPLE_DIVISOR) {
>   		dev_err(cc->dev, "Invalid clk specifier (%d, %d)\n", idx, attr);
>   		return ERR_PTR(-EINVAL);
>   	}
> @@ -230,20 +217,36 @@ static int q6afe_clock_dev_probe(struct platform_device *pdev)
>   	if (!cc)
>   		return -ENOMEM;
>   
> -	cc->clks = &q6afe_clks[0];
> -	cc->num_clks = ARRAY_SIZE(q6afe_clks);
> +	cc->dev = dev;
>   	for (i = 0; i < ARRAY_SIZE(q6afe_clks); i++) {
> -		if (!q6afe_clks[i])
> -			continue;
> +		unsigned int id = q6afe_clks[i].clk_id;
> +		struct clk_init_data init = {
> +			.name =  q6afe_clks[i].name,
> +		};
> +		struct q6afe_clk *clk;
> +
> +		clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL);
> +		if (!clk)
> +			return -ENOMEM;
> +
> +		clk->dev = dev;
> +		clk->afe_clk_id = q6afe_clks[i].afe_clk_id;
> +		clk->rate = q6afe_clks[i].rate;
> +		clk->hw.init = &init;
> +
> +		if (clk->rate)
> +			init.ops = &clk_q6afe_ops;
> +		else
> +			init.ops = &clk_vote_q6afe_ops;
>   
> -		q6afe_clks[i]->dev = dev;
> +		cc->clks[id] = clk;
>   
> -		ret = devm_clk_hw_register(dev, &q6afe_clks[i]->hw);
> +		ret = devm_clk_hw_register(dev, &clk->hw);
>   		if (ret)
>   			return ret;
>   	}
>   
> -	ret = of_clk_add_hw_provider(dev->of_node, q6afe_of_clk_hw_get, cc);
> +	ret = devm_of_clk_add_hw_provider(dev, q6afe_of_clk_hw_get, cc);
>   	if (ret)
>   		return ret;
>   
> diff --git a/sound/soc/qcom/qdsp6/q6afe.c b/sound/soc/qcom/qdsp6/q6afe.c
> index cad1cd1bfdf0..4327b72162ec 100644
> --- a/sound/soc/qcom/qdsp6/q6afe.c
> +++ b/sound/soc/qcom/qdsp6/q6afe.c
> @@ -1681,7 +1681,7 @@ int q6afe_unvote_lpass_core_hw(struct device *dev, uint32_t hw_block_id,
>   EXPORT_SYMBOL(q6afe_unvote_lpass_core_hw);
>   
>   int q6afe_vote_lpass_core_hw(struct device *dev, uint32_t hw_block_id,
> -			     char *client_name, uint32_t *client_handle)
> +			     const char *client_name, uint32_t *client_handle)
>   {
>   	struct q6afe *afe = dev_get_drvdata(dev->parent);
>   	struct afe_cmd_remote_lpass_core_hw_vote_request *vote_cfg;
> diff --git a/sound/soc/qcom/qdsp6/q6afe.h b/sound/soc/qcom/qdsp6/q6afe.h
> index 22e10269aa10..3845b56c0ed3 100644
> --- a/sound/soc/qcom/qdsp6/q6afe.h
> +++ b/sound/soc/qcom/qdsp6/q6afe.h
> @@ -236,7 +236,7 @@ int q6afe_port_set_sysclk(struct q6afe_port *port, int clk_id,
>   int q6afe_set_lpass_clock(struct device *dev, int clk_id, int clk_src,
>   			  int clk_root, unsigned int freq);
>   int q6afe_vote_lpass_core_hw(struct device *dev, uint32_t hw_block_id,
> -			     char *client_name, uint32_t *client_handle);
> +			     const char *client_name, uint32_t *client_handle);
>   int q6afe_unvote_lpass_core_hw(struct device *dev, uint32_t hw_block_id,
>   			       uint32_t client_handle);
>   #endif /* __Q6AFE_H__ */
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] ASoC: q6afe-clocks: fix reprobing of the driver
  2021-03-27  9:28 [PATCH] ASoC: q6afe-clocks: fix reprobing of the driver Dmitry Baryshkov
  2021-03-29 20:13 ` Stephen Boyd
  2021-03-30  9:08 ` Srinivas Kandagatla
@ 2021-03-30 16:05 ` Mark Brown
  2 siblings, 0 replies; 5+ messages in thread
From: Mark Brown @ 2021-03-30 16:05 UTC (permalink / raw)
  To: Liam Girdwood, Banajit Goswami, Srinivas Kandagatla,
	Dmitry Baryshkov, alsa-devel, linux-arm-msm
  Cc: Mark Brown, Bjorn Andersson, Takashi Iwai, Andy Gross

On Sat, 27 Mar 2021 12:28:57 +0300, Dmitry Baryshkov wrote:
> Q6afe-clocks driver can get reprobed. For example if the APR services
> are restarted after the firmware crash. However currently Q6afe-clocks
> driver will oops because hw.init will get cleared during first _probe
> call. Rewrite the driver to fill the clock data at runtime rather than
> using big static array of clocks.

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/1] ASoC: q6afe-clocks: fix reprobing of the driver
      commit: 96fadf7e8ff49fdb74754801228942b67c3eeebd

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-03-30 16:07 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-27  9:28 [PATCH] ASoC: q6afe-clocks: fix reprobing of the driver Dmitry Baryshkov
2021-03-29 20:13 ` Stephen Boyd
2021-03-29 21:26   ` Dmitry Baryshkov
2021-03-30  9:08 ` Srinivas Kandagatla
2021-03-30 16:05 ` Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).