Re: [PATCH v4 06/11] Bluetooth: hci_qca: Set 'bt_en_available' based on pwrseq power controllability

From: Bartosz Golaszewski

Date: Fri Jul 17 2026 - 05:31:45 EST


On Thu, 16 Jul 2026 18:18:23 +0200, Loic Poulain
<loic.poulain@xxxxxxxxxxxxxxxx> said:
> A Bluetooth device only needs the non-persistent setup if the host can
> gate its power, so that it is actually reset on the next power-on. When the
> power is controlled by a power sequencer, whether the host can gate it
> depends on the hardware wiring, e.g. the presence of the BT_EN or
> W_DISABLE2# line.
>
> Query the generic pwrseq_is_controllable() helper whenever the BT power
> comes from a sequencer, regardless of which provider it is (M2, WCN, ...).
> If the power is not controllable, clear 'bt_en_available' so that
> HCI_QUIRK_NON_PERSISTENT_SETUP is not set.
>
> This is based on Manivannan's original patch that keyed the decision off
> the W_DISABLE2# device tree property, it now uses the generic pwrseq helper
> and handles the always-on case.
>
> Signed-off-by: Loic Poulain <loic.poulain@xxxxxxxxxxxxxxxx>
> ---
> drivers/bluetooth/hci_qca.c | 13 ++++++++++++-
> 1 file changed, 12 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
> index 17f436484e1e74d1dd690ada22134315abb767c4..41e8c302abc2a820022d1783f1fad76b358ae67c 100644
> --- a/drivers/bluetooth/hci_qca.c
> +++ b/drivers/bluetooth/hci_qca.c
> @@ -2548,7 +2548,18 @@ static int qca_serdev_probe(struct serdev_device *serdev)
> return PTR_ERR(qcadev->susclk);
> }
> }
> -
> +
> + if (qcadev->bt_power->pwrseq) {
> + bt_en_available = pwrseq_is_controllable(qcadev->bt_power->pwrseq);
> + if (!bt_en_available) {
> + /* The host cannot gate the BT power individually.
> + * Treat it as always-on and drop the pwrseq handle.
> + */
> + pwrseq_power_on(qcadev->bt_power->pwrseq);
> + qcadev->bt_power->pwrseq = NULL;

Maybe a little comment saying this will be released by devres? It looks like
a leak otherwise.

Bart

> + }
> + }
> +
> err = hci_uart_register_device(&qcadev->serdev_hu, &qca_proto);
> if (err) {
> BT_ERR("serdev registration failed");
>
> --
> 2.34.1
>
>