From: bui duc phuc <[email protected]> fsl_sai_config_disable() polls TE/RE with an open-coded loop and continues silently if the bit does not clear within 1ms. Also, if regmap_read() fails, the loop condition evaluates xcsr uninitialized.
Use regmap_read_poll_timeout_atomic() and warn on timeout. Signed-off-by: bui duc phuc <[email protected]> --- sound/soc/fsl/fsl_sai.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 8315a0d8893b..f75a1d61d7b7 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -849,7 +849,8 @@ static void fsl_sai_config_disable(struct fsl_sai *sai, int dir) { unsigned int ofs = sai->soc_data->reg_offset; bool tx = dir == TX; - u32 xcsr, count = 100, mask; + u32 xcsr, mask; + int ret; if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output) mask = FSL_SAI_CSR_TERE; @@ -860,10 +861,15 @@ static void fsl_sai_config_disable(struct fsl_sai *sai, int dir) mask, 0); /* TERE will remain set till the end of current frame */ - do { - udelay(10); - regmap_read(sai->regmap, FSL_SAI_xCSR(tx, ofs), &xcsr); - } while (--count && xcsr & FSL_SAI_CSR_TERE); + ret = regmap_read_poll_timeout_atomic(sai->regmap, FSL_SAI_xCSR(tx, ofs), + xcsr, !(xcsr & FSL_SAI_CSR_TERE), + 10, 1000); + if (ret == -ETIMEDOUT) + dev_warn(&sai->pdev->dev, "%cx not disabled at frame end\n", + tx ? 'T' : 'R'); + else if (ret) + dev_err(&sai->pdev->dev, "failed to read %cSCR : %d\n", + tx ? 'T' : 'R', ret); regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs), FSL_SAI_CSR_FR, FSL_SAI_CSR_FR); -- 2.43.0
