diff options
author | yixuanjiang <yixuanjiang@google.com> | 2020-06-04 15:11:14 +0800 |
---|---|---|
committer | yixuanjiang <yixuanjiang@google.com> | 2020-06-08 18:03:19 +0800 |
commit | f49c717db2d431ea5878f72f5f696f4b803ea3c2 (patch) | |
tree | 12e00486fca74c1b29dcb225ae09593b76c6446e | |
parent | 4789539fc1e6b94e08cf01002a7ae61086d921fa (diff) | |
download | msm-extra-android-msm-bonito-4.9-r-beta-3.tar.gz |
asoc: codec: rt5514: Prevent the request of the firmware repeatedlyandroid-r-beta-3_r0.3android-r-beta-3_r0.2android-r-beta-2_r0.3android-11.0.0_r0.8android-11.0.0_r0.53android-11.0.0_r0.52android-11.0.0_r0.43android-11.0.0_r0.42android-11.0.0_r0.3android-11.0.0_r0.29android-11.0.0_r0.28android-11.0.0_r0.23android-11.0.0_r0.22android-11.0.0_r0.2android-11.0.0_r0.10android-msm-crosshatch-4.9-r-beta-3android-msm-crosshatch-4.9-android11-qpr1android-msm-crosshatch-4.9-android11android-msm-bonito-4.9-r-beta-3android-msm-bonito-4.9-r-beta-2android-msm-bonito-4.9-android11-qpr1android-msm-bonito-4.9-android11
prevent FW request during suspend mode cause the deadlock
Bug: 157705840
Change-Id: Ifc3287980539ff43116d2d2644b0c9819fc9ca6c
Signed-off-by: yixuanjiang <yixuanjiang@google.com>
-rw-r--r-- | asoc/codecs/rt5514.c | 190 | ||||
-rw-r--r-- | asoc/codecs/rt5514.h | 3 |
2 files changed, 124 insertions, 69 deletions
diff --git a/asoc/codecs/rt5514.c b/asoc/codecs/rt5514.c index 839729ea..1e9d7da2 100644 --- a/asoc/codecs/rt5514.c +++ b/asoc/codecs/rt5514.c @@ -397,15 +397,26 @@ static int rt5514_memcmp(struct rt5514_priv *rt5514, const void *cs, return res; } -static int rt5514_fw_validate(struct rt5514_priv *rt5514, - char *filename, int addr) +static const struct firmware *rt5514_request_firmware( + struct rt5514_priv *rt5514, int index) +{ + struct snd_soc_codec *codec = rt5514->codec; + + if (!rt5514->fw[index]) + request_firmware(&rt5514->fw[index], rt5514->fw_name[index], + codec->dev); + + return rt5514->fw[index]; +} + +static int rt5514_fw_validate2(struct rt5514_priv *rt5514, int index, int addr) { const struct firmware *fw = NULL; struct snd_soc_codec *codec = rt5514->codec; int ret = 0; u8 *buf; - request_firmware(&fw, filename, codec->dev); + fw = rt5514_request_firmware(rt5514, index); if (fw) { buf = kmalloc(((fw->size/8)+1)*8, GFP_KERNEL); @@ -415,14 +426,16 @@ static int rt5514_fw_validate(struct rt5514_priv *rt5514, dev_err(codec->dev, "There is no SPI driver for reading the firmware\n"); #endif - ret = rt5514_memcmp(rt5514, buf, fw->data, fw->size); + if (index) + ret = rt5514_memcmp(rt5514, buf, fw->data, fw->size); + else + ret = rt5514_memcmp(rt5514, buf + 8, fw->data + 8, + fw->size - 8); kfree(buf); - release_firmware(fw); - fw = NULL; - if (ret) { - dev_err(codec->dev, "FW validate failed %s", filename); + dev_err(codec->dev, "FW validate failed fw %d", + index); return ret; } } @@ -430,6 +443,78 @@ static int rt5514_fw_validate(struct rt5514_priv *rt5514, return 0; } +static int rt5514_fw_validate(struct rt5514_priv *rt5514, int index, int addr) +{ + struct snd_soc_codec *codec = rt5514->codec; + int ret = 0; + u8 *buf; + + switch (index) { + case 2: + if (rt5514->hotword_model_buf && rt5514->hotword_model_len) { + buf = kmalloc(((rt5514->hotword_model_len/8)+1)*8, + GFP_KERNEL); + +#if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI) + rt5514_spi_burst_read(addr, buf, + ((rt5514->hotword_model_len/8)+1)*8); +#else + dev_err(codec->dev, + "%d No SPI driver to load fw\n", __LINE__); +#endif + ret = rt5514_memcmp(rt5514, buf, + rt5514->hotword_model_buf, + rt5514->hotword_model_len); + kfree(buf); + if (ret) { + dev_err(codec->dev, + "FW validate failed fw %d", index); + return ret; + } + } else { + rt5514_fw_validate2(rt5514, index, addr); + } + + break; + + case 3: + if (rt5514->musdet_model_buf && rt5514->musdet_model_len) { + buf = kmalloc(((rt5514->musdet_model_len/8)+1)*8, + GFP_KERNEL); + +#if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI) + rt5514_spi_burst_read(addr, buf, + ((rt5514->musdet_model_len/8)+1)*8); +#else + dev_err(codec->dev, + "%d No SPI driver to load fw\n", __LINE__); +#endif + ret = rt5514_memcmp(rt5514, buf, + rt5514->musdet_model_buf, + rt5514->musdet_model_len); + + kfree(buf); + if (ret) { + dev_err(codec->dev, + "FW validate failed fw %d", + index); + return ret; + } + + } else { + rt5514_fw_validate2(rt5514, index, addr); + } + + break; + + default: + rt5514_fw_validate2(rt5514, index, addr); + break; + } + + return 0; +} + static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -437,7 +522,7 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol, struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component); struct snd_soc_codec *codec = rt5514->codec; const struct firmware *fw = NULL; - int dsp_enabled_last; + int dsp_enabled_last, i; u8 buf[8]; if (ucontrol->value.integer.value[0] == rt5514->dsp_enabled) @@ -523,7 +608,7 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol, break; } - request_firmware(&fw, RT5514_FIRMWARE1, codec->dev); + fw = rt5514_request_firmware(rt5514, 0); if (fw) { #if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI) rt5514_spi_burst_write(0x4ff60000, fw->data, @@ -532,11 +617,9 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol, dev_err(codec->dev, "%d No SPI driver to load fw\n", __LINE__); #endif - release_firmware(fw); - fw = NULL; } - request_firmware(&fw, RT5514_FIRMWARE2, codec->dev); + fw = rt5514_request_firmware(rt5514, 1); if (fw) { #if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI) rt5514_spi_burst_write(0x4ffc0000, fw->data, @@ -545,8 +628,6 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol, dev_err(codec->dev, "%d No SPI driver to load fw\n", __LINE__); #endif - release_firmware(fw); - fw = NULL; } if (rt5514->hotword_model_buf && @@ -568,8 +649,7 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol, __LINE__); #endif } else { - request_firmware(&fw, RT5514_FIRMWARE3, - codec->dev); + fw = rt5514_request_firmware(rt5514, 2); if (fw) { #if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI) rt5514_spi_burst_write(0x4ffaa800, @@ -578,8 +658,6 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol, dev_err(codec->dev, "No SPI driver to load fw\n"); #endif - release_firmware(fw); - fw = NULL; } } @@ -601,8 +679,7 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol, "No SPI driver for loading firmware\n"); #endif } else { - request_firmware(&fw, RT5514_FIRMWARE4, - codec->dev); + fw = rt5514_request_firmware(rt5514, 3); if (fw) { #if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI) rt5514_spi_burst_write(0x4ffb4800, @@ -611,58 +688,24 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol, dev_err(codec->dev, "No SPI driver to load fw\n"); #endif - release_firmware(fw); - fw = NULL; } } if (rt5514->dsp_test) { - if (rt5514_fw_validate(rt5514, RT5514_FIRMWARE1, - 0x4ff60000)) { - rt5514->dsp_enabled = 0; - regmap_multi_reg_write( - rt5514->i2c_regmap, - rt5514_i2c_patch, - ARRAY_SIZE(rt5514_i2c_patch)); - regcache_mark_dirty(rt5514->regmap); - regcache_sync(rt5514->regmap); - return 0; - } - - if (rt5514_fw_validate(rt5514, RT5514_FIRMWARE2, - 0x4ffc0000)) { - rt5514->dsp_enabled = 0; - regmap_multi_reg_write( - rt5514->i2c_regmap, - rt5514_i2c_patch, - ARRAY_SIZE(rt5514_i2c_patch)); - regcache_mark_dirty(rt5514->regmap); - regcache_sync(rt5514->regmap); - return 0; - } - - if (rt5514_fw_validate(rt5514, RT5514_FIRMWARE3, - 0x4ffaa800)) { - rt5514->dsp_enabled = 0; - regmap_multi_reg_write( - rt5514->i2c_regmap, - rt5514_i2c_patch, - ARRAY_SIZE(rt5514_i2c_patch)); - regcache_mark_dirty(rt5514->regmap); - regcache_sync(rt5514->regmap); - return 0; - } - - if (rt5514_fw_validate(rt5514, RT5514_FIRMWARE4, - 0x4ffb4800)) { - rt5514->dsp_enabled = 0; - regmap_multi_reg_write( - rt5514->i2c_regmap, - rt5514_i2c_patch, - ARRAY_SIZE(rt5514_i2c_patch)); - regcache_mark_dirty(rt5514->regmap); - regcache_sync(rt5514->regmap); - return 0; + for (i = 0; i < 4; i++) { + if (rt5514_fw_validate(rt5514, i, + rt5514->fw_addr[i])) { + rt5514->dsp_enabled = 0; + regmap_multi_reg_write( + rt5514->i2c_regmap, + rt5514_i2c_patch, + ARRAY_SIZE( + rt5514_i2c_patch)); + regcache_mark_dirty( + rt5514->regmap); + regcache_sync(rt5514->regmap); + return 0; + } } } @@ -1768,6 +1811,15 @@ static int rt5514_i2c_probe(struct i2c_client *i2c, } } + rt5514->fw_name[0] = RT5514_FIRMWARE1; + rt5514->fw_name[1] = RT5514_FIRMWARE2; + rt5514->fw_name[2] = RT5514_FIRMWARE3; + rt5514->fw_name[3] = RT5514_FIRMWARE4; + rt5514->fw_addr[0] = 0x4ff60000; + rt5514->fw_addr[1] = 0x4ffc0000; + rt5514->fw_addr[2] = 0x4ffaa800; + rt5514->fw_addr[3] = 0x4ffb4800; + ret = regmap_multi_reg_write(rt5514->i2c_regmap, rt5514_i2c_patch, ARRAY_SIZE(rt5514_i2c_patch)); if (ret != 0) diff --git a/asoc/codecs/rt5514.h b/asoc/codecs/rt5514.h index 6d28bdc1..f9b18650 100644 --- a/asoc/codecs/rt5514.h +++ b/asoc/codecs/rt5514.h @@ -282,6 +282,9 @@ struct rt5514_priv { int pll_in; int pll_out; int dsp_enabled, dsp_test; + const struct firmware *fw[4]; + char *fw_name[4]; + unsigned int fw_addr[4]; u8 *hotword_model_buf, *musdet_model_buf; unsigned int hotword_model_len, musdet_model_len; unsigned int pll3_cal_value; |