Skip to content

Commit 7e7bbdd

Browse files
Zijun Huholtmann
Zijun Hu
authored andcommitted
Bluetooth: hci_qca: Fix qca6390 enable failure after warm reboot
Warm reboot can not reset controller qca6390 due to lack of controllable power supply, so causes firmware download failure during enable. Fixed by sending VSC EDL_SOC_RESET to reset qca6390 within added device shutdown implementation. Signed-off-by: Zijun Hu <[email protected]> Tested-by: Zijun Hu <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]>
1 parent e6da0ed commit 7e7bbdd

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

drivers/bluetooth/hci_qca.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1975,6 +1975,38 @@ static void qca_serdev_remove(struct serdev_device *serdev)
19751975
hci_uart_unregister_device(&qcadev->serdev_hu);
19761976
}
19771977

1978+
static void qca_serdev_shutdown(struct device *dev)
1979+
{
1980+
int ret;
1981+
int timeout = msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS);
1982+
struct serdev_device *serdev = to_serdev_device(dev);
1983+
struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
1984+
const u8 ibs_wake_cmd[] = { 0xFD };
1985+
const u8 edl_reset_soc_cmd[] = { 0x01, 0x00, 0xFC, 0x01, 0x05 };
1986+
1987+
if (qcadev->btsoc_type == QCA_QCA6390) {
1988+
serdev_device_write_flush(serdev);
1989+
ret = serdev_device_write_buf(serdev, ibs_wake_cmd,
1990+
sizeof(ibs_wake_cmd));
1991+
if (ret < 0) {
1992+
BT_ERR("QCA send IBS_WAKE_IND error: %d", ret);
1993+
return;
1994+
}
1995+
serdev_device_wait_until_sent(serdev, timeout);
1996+
usleep_range(8000, 10000);
1997+
1998+
serdev_device_write_flush(serdev);
1999+
ret = serdev_device_write_buf(serdev, edl_reset_soc_cmd,
2000+
sizeof(edl_reset_soc_cmd));
2001+
if (ret < 0) {
2002+
BT_ERR("QCA send EDL_RESET_REQ error: %d", ret);
2003+
return;
2004+
}
2005+
serdev_device_wait_until_sent(serdev, timeout);
2006+
usleep_range(8000, 10000);
2007+
}
2008+
}
2009+
19782010
static int __maybe_unused qca_suspend(struct device *dev)
19792011
{
19802012
struct serdev_device *serdev = to_serdev_device(dev);
@@ -2102,6 +2134,7 @@ static struct serdev_device_driver qca_serdev_driver = {
21022134
.name = "hci_uart_qca",
21032135
.of_match_table = of_match_ptr(qca_bluetooth_of_match),
21042136
.acpi_match_table = ACPI_PTR(qca_bluetooth_acpi_match),
2137+
.shutdown = qca_serdev_shutdown,
21052138
.pm = &qca_pm_ops,
21062139
},
21072140
};

0 commit comments

Comments
 (0)