Commit 11e756cc authored by Guiting Shen's avatar Guiting Shen Committed by Mark Brown

ASoC: tlv320aic32x4: Fix the divide by zero

The value of register(NDAC,MDAC,NADC,MADC,BCLKN) maybe zero lead to
divide by zero in clk_aic32x4_div_recalc_rate().And the rate should be
divide by 128 if the value was zero in this function according to the
datasheet.

Add the macro AIC32X4_DIV_MAX to present the 128 and return 0 if failing
to read the value of register.
Signed-off-by: default avatarGuiting Shen <aarongt.shen@gmail.com>
Link: https://lore.kernel.org/r/20230813125520.11067-1-aarongt.shen@gmail.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent b39eee27
......@@ -321,7 +321,7 @@ static int clk_aic32x4_div_set_rate(struct clk_hw *hw, unsigned long rate,
u8 divisor;
divisor = DIV_ROUND_UP(parent_rate, rate);
if (divisor > 128)
if (divisor > AIC32X4_DIV_MAX)
return -EINVAL;
return regmap_update_bits(div->regmap, div->reg,
......@@ -334,7 +334,7 @@ static int clk_aic32x4_div_determine_rate(struct clk_hw *hw,
unsigned long divisor;
divisor = DIV_ROUND_UP(req->best_parent_rate, req->rate);
if (divisor > 128)
if (divisor > AIC32X4_DIV_MAX)
return -EINVAL;
req->rate = DIV_ROUND_UP(req->best_parent_rate, divisor);
......@@ -345,12 +345,18 @@ static unsigned long clk_aic32x4_div_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_aic32x4 *div = to_clk_aic32x4(hw);
unsigned int val;
int err;
err = regmap_read(div->regmap, div->reg, &val);
if (err)
return 0;
regmap_read(div->regmap, div->reg, &val);
val &= AIC32X4_DIV_MASK;
if (!val)
val = AIC32X4_DIV_MAX;
return DIV_ROUND_UP(parent_rate, val & AIC32X4_DIV_MASK);
return DIV_ROUND_UP(parent_rate, val);
}
static const struct clk_ops aic32x4_div_ops = {
......
......@@ -223,8 +223,9 @@ int aic32x4_register_clocks(struct device *dev, const char *mclk_name);
#define AIC32X4_REFPOWERUP_120MS 0x07
/* Common mask and enable for all of the dividers */
#define AIC32X4_DIVEN BIT(7)
#define AIC32X4_DIV_MASK GENMASK(6, 0)
#define AIC32X4_DIVEN BIT(7)
#define AIC32X4_DIV_MASK GENMASK(6, 0)
#define AIC32X4_DIV_MAX 128
/* Clock Limits */
#define AIC32X4_MAX_DOSR_FREQ 6200000
......
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