Re: [PATCH 12/12] Bluetooth: hci_qca: Fix the broken BT_EN GPIO detection for Qcom WCN devices

Dmitry Baryshkov
2026-04-22T18:13:38Z

On Wed, Apr 22, 2026 at 04:54:53PM +0530, Manivannan Sadhasivam via B4 Relay wrote:
> From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
>
> Commit 'db0ff7e15923 ("driver: bluetooth: hci_qca:fix unable to load the BT
> driver")' tried to check the presence of the BT_EN GPIO in Qcom WCN devices
> to indicate the HCI layer whether this BT device can be power controlled or
> not.
>
> But it was broken for two reasons:
>
> 1. Assumes that when devm_pwrseq_get() API returns an error, BT_EN is not
> controllable. This is no way true as the API can fail for various reasons
> and also the pwrseq-qcom-wcn driver treats the BT_EN GPIO as optional. So
> even if the GPIO is not present, it will not fail the probe and this API
> will not fail.
>
> 2. By skipping the error return, probe deferral is completely broken as the
> API may return -EPROBE_DEFER to indicate the caller that the pwrseq driver
> is not yet probed. Skipping the return value means, this driver is not
> going to depend on pwrseq driver probing again and it just assumes that
> the pwrseq is not available.
>
> So to fix these issues, fail the probe if devm_pwrseq_get() returns an
> error and if it succeeds, use the newly introduced pwrseq_is_fixed() API to
> check whether the power sequencer is fixed or not (i.e., whether the
> Bluetooth interface on the Qcom WCN device is controllable using BT_EN GPIO
> or not) and set the 'bt_en_available' flag accordingly.
>
> Cc: <stable+noautosel@kernel.org> # Depends on pwrseq change
> Fixes: db0ff7e15923 ("driver: bluetooth: hci_qca:fix unable to load the BT driver")
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> ---
> drivers/bluetooth/hci_qca.c | 15 ++++++---------
> 1 file changed, 6 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
> index 27e52b08ec47..dd1d93cbb3d8 100644
> --- a/drivers/bluetooth/hci_qca.c
> +++ b/drivers/bluetooth/hci_qca.c
> @@ -2470,16 +2470,13 @@ static int qca_serdev_probe(struct serdev_device *serdev)
> qcadev->bt_power->pwrseq = devm_pwrseq_get(&serdev->dev,
> "bluetooth");
>
> - /*
> - * Some modules have BT_EN enabled via a hardware pull-up,
> - * meaning it is not defined in the DTS and is not controlled
> - * through the power sequence. In such cases, fall through
> - * to follow the legacy flow.
> - */
> if (IS_ERR(qcadev->bt_power->pwrseq))
> - qcadev->bt_power->pwrseq = NULL;
> - else
> - break;
> + return PTR_ERR(qcadev->bt_power->pwrseq);

This will break the case of WCN399x devices without the PMU in device
tree. There is no enable-gpios since BT is not controllable, but if
there is no PMU, then devm_pwrseq_get() will always return
-EPROBE_DEFER.

> +
> + if (pwrseq_is_fixed(qcadev->bt_power->pwrseq))
> + bt_en_available = false;
> +
> + break;
> }
>
> qcadev->bt_power->dev = &serdev->dev;
>
> --
> 2.51.0
>
>

--
With best wishes
Dmitry