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

From: Manivannan Sadhasivam

Date: Thu May 07 2026 - 07:59:33 EST


On Wed, Apr 22, 2026 at 09:13:31PM +0300, Dmitry Baryshkov wrote:
> On Wed, Apr 22, 2026 at 04:54:53PM +0530, Manivannan Sadhasivam via B4 Relay wrote:
> > From: Manivannan Sadhasivam <manivannan.sadhasivam@xxxxxxxxxxxxxxxx>
> >
> > 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@xxxxxxxxxx> # Depends on pwrseq change
> > Fixes: db0ff7e15923 ("driver: bluetooth: hci_qca:fix unable to load the BT driver")
> > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@xxxxxxxxxxxxxxxx>
> > ---
> > 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.
>

Hmm. I missed that the pwrseq returns -EPROBE_DEFER even if the client doesn't
require power sequencing. It is because, it has no way to figure it out.

But I think the client can parse the regulator phandle, reach the regulator
parent, then check for the '-pmu' suffix in the compatible to make sure that it
has the power sequencing requirement. Then it can call devm_pwrseq_get() only if
that check passes.

I'll do it in a separate series though as this series fixes a different problem
altogether.

- Mani

--
மணிவண்ணன் சதாசிவம்