Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH] Bluetooth: hci_qca: Reprobe QCA6390 after hibernation
@ 2026-10-17 17:43 Nikolay Bryskin
  2026-10-17 19:30 ` bluez.test.bot
  0 siblings, 1 reply; 2+ messages in thread
From: Nikolay Bryskin @ 2026-10-17 17:43 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: Nikolay Bryskin, Bartosz Golaszewski, Marcel Holtmann,
	Luiz Augusto von Dentz, Rocky Liao, linux-arm-msm, linux-kernel

Without a way to power-cycle the SoC (no BT_EN GPIO and no power
sequencer, e.g. the ACPI-enumerated QCA6390 on the Dell XPS 13 9310),
HCI_QUIRK_NON_PERSISTENT_SETUP is not set and hdev->setup() runs only
once, at probe, on the assumption that the SoC keeps its firmware.

Hibernation breaks that assumption: the platform powers the SoC off,
and after the image is restored it is back in its ROM state. The
driver's resume callback, shared with suspend-to-idle via
SIMPLE_DEV_PM_OPS(), only clears QCA_SUSPENDING, so the first command
times out and the controller stays unusable. Error recovery and
power-cycling the adapter from userspace don't help either, because
none of them run setup again:

  Bluetooth: hci0: Opcode 0x0c01 failed: -110
  Bluetooth: hci0: command 0x0c01 tx timeout
  Bluetooth: hci0: crash the soc to collect controller dump
  Bluetooth: hci0: Opcode 0x0c05 failed: -110
  Bluetooth: hci0: Frame reassembly failed (-84)
  ...
  Bluetooth: hci0: Opcode 0x0c03 failed: -110

Give the restore phase its own callback which, in this configuration,
rebinds the driver so that probe downloads the firmware again. The
rebind is done from a work item on system_freezable_wq, as it can't
run from within a PM callback and it frees the qca_serdev the callback
works on. All other sleep transitions keep their existing callbacks.

Rebinding works here because the SoC is in its ROM state after the
restore. Rebinding while it still runs the downloaded firmware fails
the same way a warm reboot used to before commit 7e7bbddd029b
("Bluetooth: hci_qca: Fix qca6390 enable failure after warm reboot"),
which this patch doesn't change.

Tested on a Dell XPS 13 9310 (DLB16390): Bluetooth comes back about a
second after resuming from hibernation, with no command timeouts.
Suspend-to-idle is unaffected.

Fixes: e5d6468fe9d8 ("Bluetooth: hci_qca: Add support for Qualcomm Bluetooth SoC QCA6390")
Assisted-by: LLM
Signed-off-by: Nikolay Bryskin <nbryskin@gmail.com>
---
 drivers/bluetooth/hci_qca.c | 58 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 57 insertions(+), 1 deletion(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 7089e9b639b2..7bca14d364b9 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -2775,7 +2775,63 @@ static int __maybe_unused qca_resume(struct device *dev)
 	return 0;
 }
 
-static SIMPLE_DEV_PM_OPS(qca_pm_ops, qca_suspend, qca_resume);
+struct qca_reprobe {
+	struct work_struct work;
+	struct device *dev;
+};
+
+static void qca_reprobe_work(struct work_struct *work)
+{
+	struct qca_reprobe *reprobe = container_of(work, struct qca_reprobe,
+						   work);
+	int ret;
+
+	ret = device_reprobe(reprobe->dev);
+	if (ret && ret != -EPROBE_DEFER)
+		dev_err(reprobe->dev, "Failed to reprobe device (error %d)\n",
+			ret);
+
+	put_device(reprobe->dev);
+	kfree(reprobe);
+}
+
+static int __maybe_unused qca_restore(struct device *dev)
+{
+	struct serdev_device *serdev = to_serdev_device(dev);
+	struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
+	struct hci_uart *hu = &qcadev->serdev_hu;
+	struct qca_reprobe *reprobe;
+
+	qca_resume(dev);
+
+	/* Without power control hdev->setup() runs only once, at probe, as
+	 * the SoC is expected to keep its firmware. Hibernation powers the
+	 * SoC off, so rebind the driver to download the firmware again. The
+	 * rebind can't run from a PM callback, and qcadev is gone once it
+	 * does, so it gets a work item of its own.
+	 */
+	if (hci_test_quirk(hu->hdev, HCI_QUIRK_NON_PERSISTENT_SETUP))
+		return 0;
+
+	reprobe = kzalloc_obj(*reprobe);
+	if (!reprobe)
+		return -ENOMEM;
+
+	INIT_WORK(&reprobe->work, qca_reprobe_work);
+	reprobe->dev = get_device(dev);
+	queue_work(system_freezable_wq, &reprobe->work);
+
+	return 0;
+}
+
+static const struct dev_pm_ops qca_pm_ops = {
+	.suspend = pm_sleep_ptr(qca_suspend),
+	.resume = pm_sleep_ptr(qca_resume),
+	.freeze = pm_sleep_ptr(qca_suspend),
+	.thaw = pm_sleep_ptr(qca_resume),
+	.poweroff = pm_sleep_ptr(qca_suspend),
+	.restore = pm_sleep_ptr(qca_restore),
+};
 
 #ifdef CONFIG_OF
 static const struct of_device_id qca_bluetooth_of_match[] = {
-- 
2.56.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* RE: Bluetooth: hci_qca: Reprobe QCA6390 after hibernation
  2026-10-17 17:43 [PATCH] Bluetooth: hci_qca: Reprobe QCA6390 after hibernation Nikolay Bryskin
@ 2026-10-17 19:30 ` bluez.test.bot
  0 siblings, 0 replies; 2+ messages in thread
From: bluez.test.bot @ 2026-10-17 19:30 UTC (permalink / raw)
  To: linux-bluetooth, nbryskin

[-- Attachment #1: Type: text/plain, Size: 1019 bytes --]

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/series/1188025/

---Test result---

Test Summary:
CheckPatch                    PASS      0.65 seconds
VerifyFixes                   PASS      0.07 seconds
VerifySignedoff               PASS      0.07 seconds
GitLint                       PASS      6.18 seconds
SubjectPrefix                 PASS      0.26 seconds
BuildKernel                   PASS      30.00 seconds
CheckAllWarning               PASS      34.61 seconds
CheckSparse                   PASS      37.13 seconds
BuildKernel32                 PASS      30.04 seconds
CheckKernelLLVM               PASS      34.22 seconds
TestRunnerSetup               PASS      719.60 seconds
IncrementalBuild              PASS      27.51 seconds



https://github.com/bluez/bluetooth-next/pull/961

---
Regards,
Linux Bluetooth


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-10-17 19:30 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-17 17:43 [PATCH] Bluetooth: hci_qca: Reprobe QCA6390 after hibernation Nikolay Bryskin
2026-10-17 19:30 ` bluez.test.bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox