Hi Rocky, On Fri, Dec 27, 2019 at 03:21:28PM +0800, Rocky Liao wrote: > This patch adds the retry of btsoc initialization when it fails. There are > reports that the btsoc initialization may fail on some platforms but the > repro ratio is very low. The failure may be caused by UART, platform HW or > the btsoc itself but it's very difficlut to root cause, given the repro > ratio is very low. Add a retry for the btsoc initialization will resolve > most of the failures and make Bluetooth finally works. Is this problem specific to a certain chipset? What are the symptoms? > Signed-off-by: Rocky Liao <rjliao@xxxxxxxxxxxxxx> > --- > > Changes in v2: None > Changes in v3: None > > drivers/bluetooth/hci_qca.c | 26 ++++++++++++++++++++++++++ > 1 file changed, 26 insertions(+) > > diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c > index 43fd84028786..45042aa27fa4 100644 > --- a/drivers/bluetooth/hci_qca.c > +++ b/drivers/bluetooth/hci_qca.c > @@ -53,6 +53,9 @@ > /* Controller debug log header */ > #define QCA_DEBUG_HANDLE 0x2EDC > > +/* max retry count when init fails */ > +#define QCA_MAX_INIT_RETRY_COUNT 3 nit: MAX_RETRIES or MAX_INIT_RETRIES? The QCA prefix just adds noise here IMO, there's no need to disambiguate the constant from other retries since it is defined in hci_qca.c. > + > enum qca_flags { > QCA_IBS_ENABLED, > QCA_DROP_VENDOR_EVENT, > @@ -1257,7 +1260,9 @@ static int qca_setup(struct hci_uart *hu) > { > struct hci_dev *hdev = hu->hdev; > struct qca_data *qca = hu->priv; > + struct qca_serdev *qcadev; > unsigned int speed, qca_baudrate = QCA_BAUDRATE_115200; > + unsigned int init_retry_count = 0; nit: the name is a bit clunky, how about 'retries'? > enum qca_btsoc_type soc_type = qca_soc_type(hu); > const char *firmware_name = qca_get_firmware_name(hu); > int ret; > @@ -1275,6 +1280,7 @@ static int qca_setup(struct hci_uart *hu) > */ > set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); > > +retry: > if (qca_is_wcn399x(soc_type)) { > bt_dev_info(hdev, "setting up wcn3990"); > > @@ -1293,6 +1299,12 @@ static int qca_setup(struct hci_uart *hu) > return ret; > } else { > bt_dev_info(hdev, "ROME setup"); > + if (hu->serdev) { > + qcadev = serdev_device_get_drvdata(hu->serdev); > + gpiod_set_value_cansleep(qcadev->bt_en, 1); > + /* Controller needs time to bootup. */ > + msleep(150); Shouldn't this be in qca_power_on(), analogous to the power off code from "[1/4]Bluetooth: hci_qca: Add QCA Rome power off support to the qca_power_off()"? qca_power_on() should then also be called for ROME. If you opt for this it should be done in a separate patch, or possibly merged into the one mentioned above. > + } > qca_set_speed(hu, QCA_INIT_SPEED); > } > > @@ -1329,6 +1341,20 @@ static int qca_setup(struct hci_uart *hu) > * patch/nvm-config is found, so run with original fw/config. > */ > ret = 0; > + } else { > + if (init_retry_count < QCA_MAX_INIT_RETRY_COUNT) { > + qca_power_off(hdev); > + if (hu->serdev) { > + serdev_device_close(hu->serdev); > + ret = serdev_device_open(hu->serdev); > + if (ret) { > + bt_dev_err(hu->hdev, "open port fail"); nit: "failed to open port"