Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH] Bluetooth: hci_qca: Reset the in-band sleep state on power off
@ 2026-10-10 11:35 Birk Skyum
  2026-10-10 15:21 ` bluez.test.bot
  0 siblings, 1 reply; 2+ messages in thread
From: Birk Skyum @ 2026-10-10 11:35 UTC (permalink / raw)
  To: Bartosz Golaszewski, Marcel Holtmann, Luiz Augusto von Dentz
  Cc: linux-bluetooth, linux-arm-msm, linux-pm, linux-kernel

qca_power_off() cuts the power of the controller but leaves the host
side of the in-band sleep (IBS) protocol as it was. tx_ibs_state and
rx_ibs_state are initialised in qca_open() only, so a controller that
qca_setup() powers on again meets whatever state the last session ended
in.

If that state is HCI_IBS_TX_WAKING, the host is waiting for a wake
acknowledgment, and qca_hci_shutdown() has deleted the timer that
sends the wake indication again. The setup still works, because frames
bypass IBS while QCA_IBS_DISABLED is set. Once the flag is cleared,
qca_enqueue() puts every frame on tx_wait_q and nothing takes it off:

  Bluetooth: hci0: QCA setup on UART is completed
  Bluetooth: hci0: Opcode 0x0c03 failed: -110

A restore from hibernation gets there on a Lenovo Yoga Slim 7x
(WCN7850). The controller has been through a power cycle, while the
restored kernel holds the state from before the image was taken. Its
wake indications go unanswered, the commands behind them time out, and
the core closes the device and sets it up again. From then on
tx_ibs_state reads 1 in debugfs and Bluetooth stays dead until hci_uart
is reloaded.

When the controller loses power, put both sides back to asleep, which
is where qca_open() starts, and stop the two IBS timers.

Signed-off-by: Birk Skyum <birk.skyum@pm.me>
---
Tested on a Lenovo Yoga Slim 7x with Arch Linux ARM's v7.2 kernel and
hci_uart rebuilt with this change. qca_open(), qca_enqueue() and
qca_hci_shutdown() are the same there as in bluetooth-next, which this
is based on and where it builds without warnings (W=1).

Each run is a fresh boot, a hibernation with a real power-off and a
resume, with Bluetooth powered before it:

- Without the patch Bluetooth is dead afterwards in four runs out of
  four, with the log above. In the one run where I read it, debugfs
  showed tx_ibs_state=1, ibs_sent_wakes=109 and ibs_recv_wake_acks=8.
- With the patch it is powered again by itself in two runs out of two,
  about 20 seconds after the resume. The log shows a failed version
  read and "Retry BT power ON:0" before a setup that works. In the run
  where I read it, debugfs showed tx_ibs_state=0 afterwards.
- Powering the controller off and on with bluetoothctl still works.

The 20 seconds are the commands that time out before the core gives up
on the old session. This patch does not change that part.

The kernel also carried the hibernation changes in [1], [2] and [3],
without which this machine does not get this far, and a GENI serial
change that is not ready for the list.

[1] https://lore.kernel.org/r/179157746908.73485.2343672865542690797@pm.me
[2] https://lore.kernel.org/r/179158127177.70185.5691100900886332545@pm.me
[3] https://lore.kernel.org/r/179163141354.18006.80461347454353634@pm.me

 drivers/bluetooth/hci_qca.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 7089e9b63..19a75faba 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -2235,6 +2235,11 @@ static void qca_power_off(struct hci_uart *hu)
 	spin_lock_irqsave(&qca->hci_ibs_lock, flags);
 	set_bit(QCA_IBS_DISABLED, &qca->flags);
 	qca_flush(hu);
+	/* A controller that loses power is asleep when it comes back. */
+	timer_delete(&qca->wake_retrans_timer);
+	timer_delete(&qca->tx_idle_timer);
+	qca->tx_ibs_state = HCI_IBS_TX_ASLEEP;
+	qca->rx_ibs_state = HCI_IBS_RX_ASLEEP;
 	spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
 
 	/* Non-serdev device usually is powered by external power
-- 
2.56.0



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

* RE: Bluetooth: hci_qca: Reset the in-band sleep state on power off
  2026-10-10 11:35 [PATCH] Bluetooth: hci_qca: Reset the in-band sleep state on power off Birk Skyum
@ 2026-10-10 15:21 ` bluez.test.bot
  0 siblings, 0 replies; 2+ messages in thread
From: bluez.test.bot @ 2026-10-10 15:21 UTC (permalink / raw)
  To: linux-bluetooth, birk.skyum

[-- 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/1182949/

---Test result---

Test Summary:
CheckPatch                    PASS      0.51 seconds
VerifyFixes                   PASS      0.08 seconds
VerifySignedoff               PASS      0.08 seconds
GitLint                       PASS      0.22 seconds
SubjectPrefix                 PASS      0.08 seconds
BuildKernel                   PASS      22.18 seconds
CheckAllWarning               PASS      25.69 seconds
CheckSparse                   PASS      28.46 seconds
BuildKernel32                 PASS      22.38 seconds
CheckKernelLLVM               PASS      24.58 seconds
TestRunnerSetup               PASS      579.29 seconds
IncrementalBuild              PASS      21.90 seconds



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

---
Regards,
Linux Bluetooth


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

end of thread, other threads:[~2026-10-10 15:21 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-10 11:35 [PATCH] Bluetooth: hci_qca: Reset the in-band sleep state on power off Birk Skyum
2026-10-10 15:21 ` 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