From 34b8f2e9bd0c41fb607bf8b6c895134c9dcf3e23 Mon Sep 17 00:00:00 2001 From: "Xu,Baochu" Date: Thu, 24 Mar 2022 20:16:36 +0800 Subject: [PATCH] asoc: wsa881x: Fix panic on stress reboot Fix panic issue on stress reboot test. 1. Change waiting flag to indicate analog client device init completely. The new waiting flag can guarantee the analog client pointer is initilized. 2. Exit with EPROBE_DEFER while timeout on waiting flag. There is low frequency that sound card and analog client device go into same deffer probe worker. In this case, analog client device will not be probed till sound card devie probed. Then, sound card probe function call analog client device to get temparatue, this caused null pointer panic. Change-Id: Ib0e078e5591e14e5cdb69875213b8e7d403e559b --- asoc/codecs/wsa881x-analog.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/wsa881x-analog.c b/asoc/codecs/wsa881x-analog.c index 14d027ac141f..965fc56831ed 100755 --- a/asoc/codecs/wsa881x-analog.c +++ b/asoc/codecs/wsa881x-analog.c @@ -274,7 +274,8 @@ static int wsa881x_i2c_read_device(struct wsa881x_pdata *wsa881x, } pr_debug("read success reg = %x val = %x\n", reg, val); - } else { + } else if (wsa881x->client[wsa881x_index]) { + reg_addr = (u8)reg; msg = &wsa881x->xfer_msg[0]; msg->addr = wsa881x->client[wsa881x_index]->addr; @@ -302,6 +303,9 @@ static int wsa881x_i2c_read_device(struct wsa881x_pdata *wsa881x, } } val = dest[0]; + } else { + pr_err("failed for i2c client is not initilized\n"); + return -EINVAL; } return val; } @@ -1202,15 +1206,16 @@ static int wsa881x_probe(struct snd_soc_component *component) wsa881x_temp_reg_read; snd_soc_component_set_drvdata(component, &wsa_pdata[wsa881x_index]); while (retry) { - if (wsa_pdata[wsa881x_index].regmap[WSA881X_ANALOG_SLAVE] - != NULL) + if (wsa_pdata[wsa881x_index].regmap_flag) break; msleep(100); retry--; } - if (!retry) + if (!retry) { dev_err(&client->dev, "%s: max retry expired and regmap of\n" "analog slave not initilized\n", __func__); + return -EPROBE_DEFER; + } wsa881x_init_thermal(&wsa_pdata[wsa881x_index].tz_pdata); INIT_DELAYED_WORK(&wsa_pdata[wsa881x_index].ocp_ctl_work, wsa881x_ocp_ctl_work);