* [PATCH v7 0/8] arm64: dts: monaco-arduino-monza: Add support for LGA WiFi/BT module
@ 2026-10-05 12:21 Loic Poulain
2026-10-05 12:21 ` [PATCH v7 1/8] Bluetooth: hci_qca: Add M.2 Bluetooth device support using pwrseq Loic Poulain
` (7 more replies)
0 siblings, 8 replies; 24+ messages in thread
From: Loic Poulain @ 2026-10-05 12:21 UTC (permalink / raw)
To: Manivannan Sadhasivam, Bartosz Golaszewski, Marcel Holtmann,
Luiz Augusto von Dentz, Bjorn Andersson, Konrad Dybcio,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pci, linux-pm, linux-kernel, linux-arm-msm, linux-bluetooth,
devicetree, Manivannan Sadhasivam, Loic Poulain,
Bartosz Golaszewski, Dmitry Baryshkov, Wei Deng,
Krzysztof Kozlowski, Konrad Dybcio
This series describes support for the onboard WiFi/Bluetooth module
present on the Arduino VENTUNO Q (monaco) platform.
The board provides LGA pads for a wireless module. On the VENTUNO Q
these pads are populated with an NFA725B module featuring the
QCA2066 WiFi/BT combo chip. While implemented as an LGA footprint,
the design is functionally compatible with the M.2 Key E.
The NFA725B exposes WiFi over PCIe and Bluetooth over a UART.
Both interfaces are gated through the W_DISABLE1# and W_DISABLE2#
signals, as defined by the M.2 specification and handled here via
the pcie-m2 power sequencer.
This series models the hardware using the existing pwrseq framework
and connector bindings, allowing coordinated PCIe and UART bring-up.
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
---
Changes in v7:
- Rebased on linux-next (pwrseq changes dropped)
- Link to v6: https://lore.kernel.org/r/20260904-monza-wireless-v6-0-d8c5042b3efd@oss.qualcomm.com
Changes in v6:
- Rebase onto v7.3-rc1: drop the now-upstream "power: sequencing: pcie-m2:
Add QCA2066 (QCNFA765) BT serdev ID" patch and adapt to the
pwrseq_power_on()/pwrseq_power_off() -> pwrseq_enable()/pwrseq_disable()
rename that landed in this merge window.
- hci_qca: fully drop struct qca_power and move its fields directly into
struct qca_serdev, removing the bt_power indirection (Dmitry).
- Pick up Reviewed-by/Acked-by tags from Mani, Bartosz and Dmitry on the
pwrseq_is_controllable() API, the pcie-m2/qcom-wcn controllability
reporting, the bt_en_available rework and the M.2 connector support
patches.
- Drop the pwrseq-m2-bt prerequisite series link, it is now merged upstream
and included in the v7.3-rc1 base.
- Link to v5: https://lore.kernel.org/r/20260720-monza-wireless-v5-0-69ec6743543c@oss.qualcomm.com
Changes in v5:
- hci_qca: comment why the M.2 'uart' pwrseq lifetime is bound to the serdev
consumer device instead of using devm_pwrseq_get() on the controller (Bartosz).
- hci_qca: note that dropping the always-on pwrseq handle is not a leak since
the descriptor is still released by devres (Bartosz).
- Link to v4: https://lore.kernel.org/r/20260716-monza-wireless-v4-0-9b02e6f549d7@oss.qualcomm.com
Changes in v4:
- pwrseq: rename pwrseq_power_is_controllable() to pwrseq_is_controllable() (Bartosz).
- pwrseq: move the is_controllable() callback from the unit to the target (Bartosz).
- pwrseq: add might_sleep() and guard pwrseq_is_controllable() against
concurrent provider removal with rw_lock, matching pwrseq_power_on/off() (Bartosz).
- pwrseq: clarify the pwrseq_is_controllable() doc (Bartosz)
- hci_qca: lifetime follows the Bluetooth device rather than the UART controller (ChenYu).
- dt-bindings: also add the "qcom,pcie-m2-1620-lga-connector" compatible (Mani).
- arm64: dts: monaco-arduino-monza: rename the 'pcie_bridge_ep' endpoint to 'pcie_ep' (Mani).
- pwrseq: reword commmit message (Mani)
- Link to v3: https://lore.kernel.org/r/20260710-monza-wireless-v3-0-46253587af64@oss.qualcomm.com
Changes in v3:
- Embed bt_power in struct qca_serdev instead of allocating it (Dmitry).
- Add generic pwrseq_is_controllable() API + per-target .is_controllable()
callback; use it in hci_qca instead of peeking at the W_DISABLE2# property.
- Implement .is_controllable() in the pcie-m2 and qcom-wcn providers.
- Treat non-controllable BT power as always-on.
- Integrate the pending Bluetooth pwrseq patches from Mani.
- Link to v2: https://lore.kernel.org/r/20260702-monza-wireless-v2-0-7b56e2a6a6d4@oss.qualcomm.com
Changes in v2:
- hci_qca: extract M.2 pwrseq into qca_serdev_get_m2_pwrseq() helper, called
outside the SoC switch; drop duplicated of_graph logic and redundant
bt_power NULL checks (Dmitry/Mani)
- dts/bindings: use qcom,pcie-m2-1418-lga-connector (fallback
pcie-m2-e-connector) instead of the generic M.2 E-key compatible (Mani)
- Link to v1: https://lore.kernel.org/r/20260520-monza-wireless-v1-0-9f6942310653@oss.qualcomm.com
---
Loic Poulain (6):
Bluetooth: hci_qca: Set 'bt_en_available' based on pwrseq power controllability
Bluetooth: hci_qca: Embed bt_power in struct qca_serdev
Bluetooth: hci_qca: Support QCA2066 on M.2 connector via pwrseq
Bluetooth: hci_qca: Flatten struct qca_power into struct qca_serdev
dt-bindings: connector: pcie-m2-e: Add vendor LGA connector compatible
arm64: dts: qcom: monaco-arduino-monza: Add QCA2066 M.2 WiFi/BT support
Manivannan Sadhasivam (2):
Bluetooth: hci_qca: Add M.2 Bluetooth device support using pwrseq
Bluetooth: hci_qca: Rename 'power_ctrl_enabled' to 'bt_en_available'
.../bindings/connector/pcie-m2-e-connector.yaml | 8 +-
arch/arm64/boot/dts/qcom/monaco-arduino-monza.dts | 64 ++++++++-
drivers/bluetooth/hci_qca.c | 160 ++++++++++++---------
3 files changed, 157 insertions(+), 75 deletions(-)
---
base-commit: f0406245cb9855e6318335a8a223551354291a46
change-id: 20260520-monza-wireless-e6ce7f013f38
Best regards,
--
Loic Poulain <loic.poulain@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 24+ messages in thread* [PATCH v7 1/8] Bluetooth: hci_qca: Add M.2 Bluetooth device support using pwrseq
2026-10-05 12:21 [PATCH v7 0/8] arm64: dts: monaco-arduino-monza: Add support for LGA WiFi/BT module Loic Poulain
@ 2026-10-05 12:21 ` Loic Poulain
2026-10-05 12:29 ` sashiko-bot
2026-10-05 13:01 ` arm64: dts: monaco-arduino-monza: Add support for LGA WiFi/BT module bluez.test.bot
2026-10-05 12:21 ` [PATCH v7 2/8] Bluetooth: hci_qca: Rename 'power_ctrl_enabled' to 'bt_en_available' Loic Poulain
` (6 subsequent siblings)
7 siblings, 2 replies; 24+ messages in thread
From: Loic Poulain @ 2026-10-05 12:21 UTC (permalink / raw)
To: Manivannan Sadhasivam, Bartosz Golaszewski, Marcel Holtmann,
Luiz Augusto von Dentz, Bjorn Andersson, Konrad Dybcio,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pci, linux-pm, linux-kernel, linux-arm-msm, linux-bluetooth,
devicetree, Manivannan Sadhasivam, Loic Poulain,
Bartosz Golaszewski, Dmitry Baryshkov, Wei Deng
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Power supply to the M.2 Bluetooth device attached to the host using M.2
connector is controlled using the 'uart' pwrseq device. So add support for
getting the pwrseq device if the OF graph link is present. Once obtained,
the existing pwrseq APIs can be used to control the power supplies of the
M.2 card.
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Tested-by: Wei Deng <wei.deng@oss.qualcomm.com>
---
drivers/bluetooth/hci_qca.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 7089e9b639b2aad2d5ad2d43b07f495833757805..e249fc6e44479142e25af4e37bc4e1bdba13cd98 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -25,6 +25,7 @@
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_graph.h>
#include <linux/acpi.h>
#include <linux/platform_device.h>
#include <linux/pwrseq/consumer.h>
@@ -2454,6 +2455,18 @@ static int qca_serdev_probe(struct serdev_device *serdev)
case QCA_WCN6750:
case QCA_WCN6855:
case QCA_WCN7850:
+ /*
+ * OF graph link is only present for BT devices attached through
+ * the M.2 Key E connector.
+ */
+ if (of_graph_is_present(dev_of_node(&serdev->ctrl->dev))) {
+ qcadev->bt_power->pwrseq = devm_pwrseq_get(&serdev->ctrl->dev,
+ "uart");
+ if (IS_ERR(qcadev->bt_power->pwrseq))
+ return PTR_ERR(qcadev->bt_power->pwrseq);
+ break;
+ }
+
if (!device_property_present(&serdev->dev, "enable-gpios")) {
/*
* Backward compatibility with old DT sources. If the
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: [PATCH v7 1/8] Bluetooth: hci_qca: Add M.2 Bluetooth device support using pwrseq
2026-10-05 12:21 ` [PATCH v7 1/8] Bluetooth: hci_qca: Add M.2 Bluetooth device support using pwrseq Loic Poulain
@ 2026-10-05 12:29 ` sashiko-bot
2026-10-05 13:01 ` arm64: dts: monaco-arduino-monza: Add support for LGA WiFi/BT module bluez.test.bot
1 sibling, 0 replies; 24+ messages in thread
From: sashiko-bot @ 2026-10-05 12:29 UTC (permalink / raw)
To: Loic Poulain; +Cc: robh, linux-pci, conor+dt, devicetree
> From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
>
> Power supply to the M.2 Bluetooth device attached to the host using M.2
> connector is controlled using the 'uart' pwrseq device. So add support for
> getting the pwrseq device if the OF graph link is present. Once obtained,
> the existing pwrseq APIs can be used to control the power supplies of the
> M.2 card.
>
> Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261005-monza-wireless-v7-0-5a6de7662dcb@oss.qualcomm.com?part=1
^ permalink raw reply [flat|nested] 24+ messages in thread
* RE: arm64: dts: monaco-arduino-monza: Add support for LGA WiFi/BT module
2026-10-05 12:21 ` [PATCH v7 1/8] Bluetooth: hci_qca: Add M.2 Bluetooth device support using pwrseq Loic Poulain
2026-10-05 12:29 ` sashiko-bot
@ 2026-10-05 13:01 ` bluez.test.bot
1 sibling, 0 replies; 24+ messages in thread
From: bluez.test.bot @ 2026-10-05 13:01 UTC (permalink / raw)
To: linux-bluetooth, loic.poulain
[-- Attachment #1: Type: text/plain, Size: 11564 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/1179616/
---Test result---
Test Summary:
CheckPatch PASS 5.40 seconds
VerifyFixes PASS 0.09 seconds
VerifySignedoff PASS 0.09 seconds
GitLint FAIL 2.19 seconds
SubjectPrefix FAIL 0.71 seconds
BuildKernel FAIL 23.74 seconds
CheckAllWarning FAIL 26.98 seconds
CheckSparse FAIL 29.70 seconds
BuildKernel32 FAIL 25.13 seconds
CheckKernelLLVM FAIL 27.74 seconds
TestRunnerSetup FAIL 758.78 seconds
TestRunner_l2cap-tester FAIL 0.10 seconds
TestRunner_iso-tester FAIL 0.12 seconds
TestRunner_bnep-tester FAIL 0.10 seconds
TestRunner_mgmt-tester FAIL 0.25 seconds
TestRunner_rfcomm-tester FAIL 0.10 seconds
TestRunner_sco-tester FAIL 0.10 seconds
TestRunner_ioctl-tester FAIL 0.09 seconds
TestRunner_mesh-tester FAIL 0.10 seconds
TestRunner_smp-tester FAIL 0.10 seconds
TestRunner_userchan-tester FAIL 0.10 seconds
TestRunner_6lowpan-tester FAIL 0.10 seconds
IncrementalBuild FAIL 31.81 seconds
Details
##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[v7,3/8] Bluetooth: hci_qca: Set 'bt_en_available' based on pwrseq power controllability
1: T1 Title exceeds max length (88>80): "[v7,3/8] Bluetooth: hci_qca: Set 'bt_en_available' based on pwrseq power controllability"
##############################
Test: SubjectPrefix - FAIL
Desc: Check subject contains "Bluetooth" prefix
Output:
"Bluetooth: " prefix is not specified in the subject
"Bluetooth: " prefix is not specified in the subject
##############################
Test: BuildKernel - FAIL
Desc: Build Kernel for Bluetooth
Output:
drivers/bluetooth/hci_qca.c: In function ‘qca_serdev_probe’:
drivers/bluetooth/hci_qca.c:2557:35: error: implicit declaration of function ‘pwrseq_is_controllable’ [-Wimplicit-function-declaration]
2557 | bt_en_available = pwrseq_is_controllable(qcadev->pwrseq);
| ^~~~~~~~~~~~~~~~~~~~~~
make[4]: *** [scripts/Makefile.build:290: drivers/bluetooth/hci_qca.o] Error 1
make[3]: *** [scripts/Makefile.build:551: drivers/bluetooth] Error 2
make[2]: *** [scripts/Makefile.build:551: drivers] Error 2
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [/home/runner/work/bluetooth-next/bluetooth-next/src/src/Makefile:2229: .] Error 2
make: *** [Makefile:248: __sub-make] Error 2
##############################
Test: CheckAllWarning - FAIL
Desc: Run linux kernel with all warning enabled
Output:
drivers/bluetooth/hci_qca.c: In function ‘qca_serdev_probe’:
drivers/bluetooth/hci_qca.c:2557:35: error: implicit declaration of function ‘pwrseq_is_controllable’ [-Wimplicit-function-declaration]
2557 | bt_en_available = pwrseq_is_controllable(qcadev->pwrseq);
| ^~~~~~~~~~~~~~~~~~~~~~
make[4]: *** [scripts/Makefile.build:290: drivers/bluetooth/hci_qca.o] Error 1
make[4]: *** Waiting for unfinished jobs....
make[3]: *** [scripts/Makefile.build:551: drivers/bluetooth] Error 2
make[2]: *** [scripts/Makefile.build:551: drivers] Error 2
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [/home/runner/work/bluetooth-next/bluetooth-next/src/src/Makefile:2229: .] Error 2
make: *** [Makefile:248: __sub-make] Error 2
##############################
Test: CheckSparse - FAIL
Desc: Run sparse tool with linux kernel
Output:
net/bluetooth/hci_event.c: note: in included file (through include/net/bluetooth/hci_core.h):
./include/net/bluetooth/hci.h:2975:47: warning: array of flexible structures
./include/net/bluetooth/hci.h:3061:43: warning: array of flexible structures
drivers/bluetooth/hci_qca.c: In function ‘qca_serdev_probe’:
drivers/bluetooth/hci_qca.c:2557:35: error: implicit declaration of function ‘pwrseq_is_controllable’ [-Wimplicit-function-declaration]
2557 | bt_en_available = pwrseq_is_controllable(qcadev->pwrseq);
| ^~~~~~~~~~~~~~~~~~~~~~
make[4]: *** [scripts/Makefile.build:290: drivers/bluetooth/hci_qca.o] Error 1
make[4]: *** Waiting for unfinished jobs....
make[3]: *** [scripts/Makefile.build:551: drivers/bluetooth] Error 2
make[2]: *** [scripts/Makefile.build:551: drivers] Error 2
make[2]: *** Waiting for unfinished jobs....
net/bluetooth/hci_codec.c: note: in included file:
./include/net/bluetooth/hci_core.h:151:35: warning: array of flexible structures
net/bluetooth/sco.c: note: in included file:
./include/net/bluetooth/hci_core.h:151:35: warning: array of flexible structures
make[1]: *** [/home/runner/work/bluetooth-next/bluetooth-next/src/src/Makefile:2229: .] Error 2
make: *** [Makefile:248: __sub-make] Error 2
##############################
Test: BuildKernel32 - FAIL
Desc: Build 32bit Kernel for Bluetooth
Output:
drivers/bluetooth/hci_qca.c: In function ‘qca_serdev_probe’:
drivers/bluetooth/hci_qca.c:2557:35: error: implicit declaration of function ‘pwrseq_is_controllable’ [-Wimplicit-function-declaration]
2557 | bt_en_available = pwrseq_is_controllable(qcadev->pwrseq);
| ^~~~~~~~~~~~~~~~~~~~~~
make[4]: *** [scripts/Makefile.build:290: drivers/bluetooth/hci_qca.o] Error 1
make[3]: *** [scripts/Makefile.build:551: drivers/bluetooth] Error 2
make[2]: *** [scripts/Makefile.build:551: drivers] Error 2
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [/home/runner/work/bluetooth-next/bluetooth-next/src/src/Makefile:2229: .] Error 2
make: *** [Makefile:248: __sub-make] Error 2
##############################
Test: CheckKernelLLVM - FAIL
Desc: Build kernel with LLVM + context analysis
Output:
drivers/bluetooth/hci_qca.c:2557:21: error: call to undeclared function 'pwrseq_is_controllable'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
2557 | bt_en_available = pwrseq_is_controllable(qcadev->pwrseq);
| ^
1 error generated.
make[4]: *** [scripts/Makefile.build:290: drivers/bluetooth/hci_qca.o] Error 1
make[4]: *** Waiting for unfinished jobs....
make[3]: *** [scripts/Makefile.build:551: drivers/bluetooth] Error 2
make[2]: *** [scripts/Makefile.build:551: drivers] Error 2
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [/home/runner/work/bluetooth-next/bluetooth-next/src/src/Makefile:2229: .] Error 2
make: *** [Makefile:248: __sub-make] Error 2
##############################
Test: TestRunnerSetup - FAIL
Desc: Setup kernel and bluez for test-runner
Output:
Kernel:
drivers/bluetooth/hci_qca.c: In function ‘qca_serdev_probe’:
drivers/bluetooth/hci_qca.c:2557:35: error: implicit declaration of function ‘pwrseq_is_controllable’ [-Wimplicit-function-declaration]
2557 | bt_en_available = pwrseq_is_controllable(qcadev->pwrseq);
| ^~~~~~~~~~~~~~~~~~~~~~
make[4]: *** [scripts/Makefile.build:290: drivers/bluetooth/hci_qca.o] Error 1
make[3]: *** [scripts/Makefile.build:551: drivers/bluetooth] Error 2
make[3]: *** Waiting for unfinished jobs....
make[2]: *** [scripts/Makefile.build:551: drivers] Error 2
make[1]: *** [/home/runner/work/bluetooth-next/bluetooth-next/src/src/Makefile:2229: .] Error 2
make: *** [Makefile:248: __sub-make] Error 2
##############################
Test: TestRunner_l2cap-tester - FAIL
Desc: Run l2cap-tester with test-runner
Output:
No kernel image found
##############################
Test: TestRunner_iso-tester - FAIL
Desc: Run iso-tester with test-runner
Output:
No kernel image found
##############################
Test: TestRunner_bnep-tester - FAIL
Desc: Run bnep-tester with test-runner
Output:
No kernel image found
##############################
Test: TestRunner_mgmt-tester - FAIL
Desc: Run mgmt-tester with test-runner
Output:
No kernel image found
##############################
Test: TestRunner_rfcomm-tester - FAIL
Desc: Run rfcomm-tester with test-runner
Output:
No kernel image found
##############################
Test: TestRunner_sco-tester - FAIL
Desc: Run sco-tester with test-runner
Output:
No kernel image found
##############################
Test: TestRunner_ioctl-tester - FAIL
Desc: Run ioctl-tester with test-runner
Output:
No kernel image found
##############################
Test: TestRunner_mesh-tester - FAIL
Desc: Run mesh-tester with test-runner
Output:
No kernel image found
##############################
Test: TestRunner_smp-tester - FAIL
Desc: Run smp-tester with test-runner
Output:
No kernel image found
##############################
Test: TestRunner_userchan-tester - FAIL
Desc: Run userchan-tester with test-runner
Output:
No kernel image found
##############################
Test: TestRunner_6lowpan-tester - FAIL
Desc: Run 6lowpan-tester with test-runner
Output:
No kernel image found
##############################
Test: IncrementalBuild - FAIL
Desc: Incremental build with the patches in the series
Output:
drivers/bluetooth/hci_qca.c: In function ‘qca_serdev_probe’:
drivers/bluetooth/hci_qca.c:2562:35: error: implicit declaration of function ‘pwrseq_is_controllable’ [-Wimplicit-function-declaration]
2562 | bt_en_available = pwrseq_is_controllable(qcadev->bt_power->pwrseq);
| ^~~~~~~~~~~~~~~~~~~~~~
drivers/bluetooth/hci_qca.c:2569:25: error: implicit declaration of function ‘pwrseq_power_on’ [-Wimplicit-function-declaration]
2569 | pwrseq_power_on(qcadev->bt_power->pwrseq);
| ^~~~~~~~~~~~~~~
make[4]: *** [scripts/Makefile.build:290: drivers/bluetooth/hci_qca.o] Error 1
make[3]: *** [scripts/Makefile.build:551: drivers/bluetooth] Error 2
make[2]: *** [scripts/Makefile.build:551: drivers] Error 2
make[1]: *** [/home/runner/work/bluetooth-next/bluetooth-next/src/src/Makefile:2229: .] Error 2
make: *** [Makefile:248: __sub-make] Error 2
[v7,3/8] Bluetooth: hci_qca: Set 'bt_en_available' based on pwrseq power controllability
drivers/bluetooth/hci_qca.c: In function ‘qca_serdev_probe’:
drivers/bluetooth/hci_qca.c:2562:35: error: implicit declaration of function ‘pwrseq_is_controllable’ [-Wimplicit-function-declaration]
2562 | bt_en_available = pwrseq_is_controllable(qcadev->bt_power->pwrseq);
| ^~~~~~~~~~~~~~~~~~~~~~
drivers/bluetooth/hci_qca.c:2569:25: error: implicit declaration of function ‘pwrseq_power_on’ [-Wimplicit-function-declaration]
2569 | pwrseq_power_on(qcadev->bt_power->pwrseq);
| ^~~~~~~~~~~~~~~
make[4]: *** [scripts/Makefile.build:290: drivers/bluetooth/hci_qca.o] Error 1
make[3]: *** [scripts/Makefile.build:551: drivers/bluetooth] Error 2
make[2]: *** [scripts/Makefile.build:551: drivers] Error 2
make[1]: *** [/home/runner/work/bluetooth-next/bluetooth-next/src/src/Makefile:2229: .] Error 2
make: *** [Makefile:248: __sub-make] Error 2
https://github.com/bluez/bluetooth-next/pull/862
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v7 2/8] Bluetooth: hci_qca: Rename 'power_ctrl_enabled' to 'bt_en_available'
2026-10-05 12:21 [PATCH v7 0/8] arm64: dts: monaco-arduino-monza: Add support for LGA WiFi/BT module Loic Poulain
2026-10-05 12:21 ` [PATCH v7 1/8] Bluetooth: hci_qca: Add M.2 Bluetooth device support using pwrseq Loic Poulain
@ 2026-10-05 12:21 ` Loic Poulain
2026-10-05 12:28 ` sashiko-bot
2026-10-05 12:21 ` [PATCH v7 3/8] Bluetooth: hci_qca: Set 'bt_en_available' based on pwrseq power controllability Loic Poulain
` (5 subsequent siblings)
7 siblings, 1 reply; 24+ messages in thread
From: Loic Poulain @ 2026-10-05 12:21 UTC (permalink / raw)
To: Manivannan Sadhasivam, Bartosz Golaszewski, Marcel Holtmann,
Luiz Augusto von Dentz, Bjorn Andersson, Konrad Dybcio,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pci, linux-pm, linux-kernel, linux-arm-msm, linux-bluetooth,
devicetree, Manivannan Sadhasivam, Loic Poulain, Dmitry Baryshkov,
Bartosz Golaszewski, Wei Deng
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
'power_ctrl_enabled' flag is used to indicate the availability of the BT_EN
GPIO in devicetree. But the naming causes confusion with the new pwrctrl
framework.
So rename it to 'bt_en_available' to make it clear and explicit.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Tested-by: Wei Deng <wei.deng@oss.qualcomm.com>
---
drivers/bluetooth/hci_qca.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index e249fc6e44479142e25af4e37bc4e1bdba13cd98..f53f95601693dcd8356b4b825776317061050f1b 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -2402,7 +2402,7 @@ static int qca_serdev_probe(struct serdev_device *serdev)
struct hci_dev *hdev;
const struct qca_device_data *data;
int err;
- bool power_ctrl_enabled = true;
+ bool bt_en_available = true;
qcadev = devm_kzalloc(&serdev->dev, sizeof(*qcadev), GFP_KERNEL);
if (!qcadev)
@@ -2510,7 +2510,7 @@ static int qca_serdev_probe(struct serdev_device *serdev)
(data->soc_type == QCA_WCN6750 ||
data->soc_type == QCA_WCN6855 ||
data->soc_type == QCA_WCN7850))
- power_ctrl_enabled = false;
+ bt_en_available = false;
qcadev->sw_ctrl = devm_gpiod_get_optional(&serdev->dev, "swctrl",
GPIOD_IN);
@@ -2548,7 +2548,7 @@ static int qca_serdev_probe(struct serdev_device *serdev)
}
if (!qcadev->bt_en)
- power_ctrl_enabled = false;
+ bt_en_available = false;
qcadev->susclk = devm_clk_get_optional_enabled_with_rate(
&serdev->dev, NULL, SUSCLK_RATE_32KHZ);
@@ -2566,7 +2566,7 @@ static int qca_serdev_probe(struct serdev_device *serdev)
hdev = qcadev->serdev_hu.hdev;
- if (power_ctrl_enabled) {
+ if (bt_en_available) {
hci_set_quirk(hdev, HCI_QUIRK_NON_PERSISTENT_SETUP);
hdev->shutdown = qca_hci_shutdown;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: [PATCH v7 2/8] Bluetooth: hci_qca: Rename 'power_ctrl_enabled' to 'bt_en_available'
2026-10-05 12:21 ` [PATCH v7 2/8] Bluetooth: hci_qca: Rename 'power_ctrl_enabled' to 'bt_en_available' Loic Poulain
@ 2026-10-05 12:28 ` sashiko-bot
0 siblings, 0 replies; 24+ messages in thread
From: sashiko-bot @ 2026-10-05 12:28 UTC (permalink / raw)
To: Loic Poulain; +Cc: linux-pci, devicetree, conor+dt, robh
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] bluetooth: semantic mismatch in renaming power_ctrl_enabled to bt_en_available
--
commit a629aed3c3c3f22e42d5d786579731613da2a200
Author: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Bluetooth: hci_qca: Rename 'power_ctrl_enabled' to 'bt_en_available'
The commit renames the 'power_ctrl_enabled' flag to 'bt_en_available' to avoid
confusion with the new pwrctrl framework. It claims the flag is used to
indicate the availability of the BT_EN GPIO in devicetree.
> diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
> index e249fc6e44479..f53f95601693d 100644
> --- a/drivers/bluetooth/hci_qca.c
> +++ b/drivers/bluetooth/hci_qca.c
> @@ -2402,7 +2402,7 @@ static int qca_serdev_probe(struct serdev_device *serdev)
> struct hci_dev *hdev;
> const struct qca_device_data *data;
> int err;
> - bool power_ctrl_enabled = true;
> + bool bt_en_available = true;
[Severity: Medium]
Does initializing this to true imply that BT_EN is available by default, even
when it is not?
[ ... ]
> @@ -2510,7 +2510,7 @@ static int qca_serdev_probe(struct serdev_device *serdev)
> (data->soc_type == QCA_WCN6750 ||
> data->soc_type == QCA_WCN6855 ||
> data->soc_type == QCA_WCN7850))
> - power_ctrl_enabled = false;
> + bt_en_available = false;
[Severity: Medium]
For SoCs like QCA_WCN3990, if the BT_EN GPIO is missing but regulators exist,
this variable remains true because the logic to clear it is strictly limited
to WCN6750/WCN6855/WCN7850.
Does this create a semantic mismatch where the variable name suggests BT_EN is
available, but it is actually tracking whether any form of power control is
active?
[ ... ]
> @@ -2566,7 +2566,7 @@ static int qca_serdev_probe(struct serdev_device *serdev)
>
> hdev = qcadev->serdev_hu.hdev;
>
> - if (power_ctrl_enabled) {
> + if (bt_en_available) {
> hci_set_quirk(hdev, HCI_QUIRK_NON_PERSISTENT_SETUP);
> hdev->shutdown = qca_hci_shutdown;
> }
[Severity: Medium]
The qca_hci_shutdown hook is assigned based on this flag to ensure power
control teardown.
Since this flag must remain true for devices like QCA_WCN3990 to execute the
shutdown hook to disable their regulators (even if they lack a BT_EN GPIO),
was the original 'power_ctrl_enabled' name actually more accurate?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261005-monza-wireless-v7-0-5a6de7662dcb@oss.qualcomm.com?part=2
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v7 3/8] Bluetooth: hci_qca: Set 'bt_en_available' based on pwrseq power controllability
2026-10-05 12:21 [PATCH v7 0/8] arm64: dts: monaco-arduino-monza: Add support for LGA WiFi/BT module Loic Poulain
2026-10-05 12:21 ` [PATCH v7 1/8] Bluetooth: hci_qca: Add M.2 Bluetooth device support using pwrseq Loic Poulain
2026-10-05 12:21 ` [PATCH v7 2/8] Bluetooth: hci_qca: Rename 'power_ctrl_enabled' to 'bt_en_available' Loic Poulain
@ 2026-10-05 12:21 ` Loic Poulain
2026-10-05 12:33 ` sashiko-bot
2026-10-05 12:21 ` [PATCH v7 4/8] Bluetooth: hci_qca: Embed bt_power in struct qca_serdev Loic Poulain
` (4 subsequent siblings)
7 siblings, 1 reply; 24+ messages in thread
From: Loic Poulain @ 2026-10-05 12:21 UTC (permalink / raw)
To: Manivannan Sadhasivam, Bartosz Golaszewski, Marcel Holtmann,
Luiz Augusto von Dentz, Bjorn Andersson, Konrad Dybcio,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pci, linux-pm, linux-kernel, linux-arm-msm, linux-bluetooth,
devicetree, Manivannan Sadhasivam, Loic Poulain,
Bartosz Golaszewski
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.
Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
---
drivers/bluetooth/hci_qca.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index f53f95601693dcd8356b4b825776317061050f1b..20d8c5e890a8903a07c3e7e37d037c44d383e8df 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -2557,7 +2557,20 @@ 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.
+ * The descriptor itself is still released by devres,
+ * so dropping the handle here is not a leak.
+ */
+ pwrseq_power_on(qcadev->bt_power->pwrseq);
+ qcadev->bt_power->pwrseq = NULL;
+ }
+ }
+
err = hci_uart_register_device(&qcadev->serdev_hu, &qca_proto);
if (err) {
BT_ERR("serdev registration failed");
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: [PATCH v7 3/8] Bluetooth: hci_qca: Set 'bt_en_available' based on pwrseq power controllability
2026-10-05 12:21 ` [PATCH v7 3/8] Bluetooth: hci_qca: Set 'bt_en_available' based on pwrseq power controllability Loic Poulain
@ 2026-10-05 12:33 ` sashiko-bot
0 siblings, 0 replies; 24+ messages in thread
From: sashiko-bot @ 2026-10-05 12:33 UTC (permalink / raw)
To: Loic Poulain; +Cc: devicetree, linux-pci, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] bluetooth: hci_qca: missing error check for pwrseq_enable() in probe
--
commit 842e42b3b693b54c6eab8132c98045df38fc5343
Author: Loic Poulain <loic.poulain@oss.qualcomm.com>
Bluetooth: hci_qca: Set 'bt_en_available' based on pwrseq power controllability
This commit updates the driver to query pwrseq_is_controllable() when Bluetooth
power comes from a sequencer. If the power is not controllable, it clears
bt_en_available so that the non-persistent setup quirk is not set and treats
the device as always-on.
> diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
> index f53f95601693d..20d8c5e890a89 100644
> --- a/drivers/bluetooth/hci_qca.c
> +++ b/drivers/bluetooth/hci_qca.c
> @@ -2557,7 +2557,20 @@ 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.
> + * The descriptor itself is still released by devres,
> + * so dropping the handle here is not a leak.
> + */
> + pwrseq_power_on(qcadev->bt_power->pwrseq);
[Severity: High]
Does this code need to check the return value of pwrseq_power_on()?
If powering on the Bluetooth hardware fails, the driver incorrectly continues
probing and returns success. This leads to silent hardware initialization
failures and downstream communication timeouts when the host attempts to
interact with the unpowered controller.
Note: The undefined function typo (pwrseq_power_on) present in this patch
is fixed in a subsequent patch in this series (commit 'Bluetooth: hci_qca:
Flatten struct qca_power into struct qca_serdev'), but the missing error
check for the corrected pwrseq_enable() call remains unfixed in the final
state of the series.
> + qcadev->bt_power->pwrseq = NULL;
> + }
> + }
> +
> err = hci_uart_register_device(&qcadev->serdev_hu, &qca_proto);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261005-monza-wireless-v7-0-5a6de7662dcb@oss.qualcomm.com?part=3
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v7 4/8] Bluetooth: hci_qca: Embed bt_power in struct qca_serdev
2026-10-05 12:21 [PATCH v7 0/8] arm64: dts: monaco-arduino-monza: Add support for LGA WiFi/BT module Loic Poulain
` (2 preceding siblings ...)
2026-10-05 12:21 ` [PATCH v7 3/8] Bluetooth: hci_qca: Set 'bt_en_available' based on pwrseq power controllability Loic Poulain
@ 2026-10-05 12:21 ` Loic Poulain
2026-10-05 12:29 ` sashiko-bot
2026-10-05 12:21 ` [PATCH v7 5/8] Bluetooth: hci_qca: Support QCA2066 on M.2 connector via pwrseq Loic Poulain
` (3 subsequent siblings)
7 siblings, 1 reply; 24+ messages in thread
From: Loic Poulain @ 2026-10-05 12:21 UTC (permalink / raw)
To: Manivannan Sadhasivam, Bartosz Golaszewski, Marcel Holtmann,
Luiz Augusto von Dentz, Bjorn Andersson, Konrad Dybcio,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pci, linux-pm, linux-kernel, linux-arm-msm, linux-bluetooth,
devicetree, Manivannan Sadhasivam, Loic Poulain,
Bartosz Golaszewski
'bt_power' is allocated dynamically only for a subset of SOC types, using a
switch on the SOC type that mirrors the one that follows it. This is about
to become pointless as the power sequencer path (used by M.2 modules) is
independent of the SOC type and needs 'bt_power' populated for any type.
Embed 'struct qca_power' directly in 'struct qca_serdev' instead of
allocating it separately. This drops the extra allocation and its dedicated
SOC-type switch, and removes the need for NULL checks on the pointer.
No functional change intended.
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
---
drivers/bluetooth/hci_qca.c | 72 ++++++++++++++++-----------------------------
1 file changed, 26 insertions(+), 46 deletions(-)
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 20d8c5e890a8903a07c3e7e37d037c44d383e8df..1d27ff98034ba99d0783e48db5c605f3b31117ea 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -225,7 +225,7 @@ struct qca_serdev {
struct gpio_desc *sw_ctrl;
struct clk *susclk;
enum qca_btsoc_type btsoc_type;
- struct qca_power *bt_power;
+ struct qca_power bt_power;
u32 init_speed;
u32 oper_speed;
bool bdaddr_property_broken;
@@ -1779,7 +1779,7 @@ static int qca_regulator_init(struct hci_uart *hu)
*/
qcadev = serdev_device_get_drvdata(hu->serdev);
- if (!qcadev->bt_power->vregs_on) {
+ if (!qcadev->bt_power.vregs_on) {
serdev_device_close(hu->serdev);
ret = qca_regulator_enable(qcadev);
if (ret)
@@ -2245,7 +2245,7 @@ static void qca_power_off(struct hci_uart *hu)
return;
qcadev = serdev_device_get_drvdata(hu->serdev);
- power = qcadev->bt_power;
+ power = &qcadev->bt_power;
switch (soc_type) {
case QCA_WCN3988:
@@ -2265,7 +2265,7 @@ static void qca_power_off(struct hci_uart *hu)
break;
}
- if (power && power->pwrseq) {
+ if (power->pwrseq) {
pwrseq_disable(power->pwrseq);
set_bit(QCA_BT_OFF, &qca->flags);
return;
@@ -2322,7 +2322,7 @@ static int qca_hci_shutdown(struct hci_dev *hdev)
static int qca_regulator_enable(struct qca_serdev *qcadev)
{
- struct qca_power *power = qcadev->bt_power;
+ struct qca_power *power = &qcadev->bt_power;
int ret;
if (power->pwrseq)
@@ -2354,7 +2354,7 @@ static void qca_regulator_disable(struct qca_serdev *qcadev)
if (!qcadev)
return;
- power = qcadev->bt_power;
+ power = &qcadev->bt_power;
/* Already disabled? */
if (!power->vregs_on)
@@ -2426,26 +2426,6 @@ static int qca_serdev_probe(struct serdev_device *serdev)
else
qcadev->btsoc_type = QCA_ROME;
- switch (qcadev->btsoc_type) {
- case QCA_QCA6390:
- case QCA_WCN3950:
- case QCA_WCN3988:
- case QCA_WCN3990:
- case QCA_WCN3991:
- case QCA_WCN3998:
- case QCA_WCN6750:
- case QCA_WCN6855:
- case QCA_WCN7850:
- qcadev->bt_power = devm_kzalloc(&serdev->dev,
- sizeof(struct qca_power),
- GFP_KERNEL);
- if (!qcadev->bt_power)
- return -ENOMEM;
- break;
- default:
- break;
- }
-
switch (qcadev->btsoc_type) {
case QCA_WCN3950:
case QCA_WCN3988:
@@ -2460,10 +2440,10 @@ static int qca_serdev_probe(struct serdev_device *serdev)
* the M.2 Key E connector.
*/
if (of_graph_is_present(dev_of_node(&serdev->ctrl->dev))) {
- qcadev->bt_power->pwrseq = devm_pwrseq_get(&serdev->ctrl->dev,
- "uart");
- if (IS_ERR(qcadev->bt_power->pwrseq))
- return PTR_ERR(qcadev->bt_power->pwrseq);
+ qcadev->bt_power.pwrseq = devm_pwrseq_get(&serdev->ctrl->dev,
+ "uart");
+ if (IS_ERR(qcadev->bt_power.pwrseq))
+ return PTR_ERR(qcadev->bt_power.pwrseq);
break;
}
@@ -2474,8 +2454,8 @@ static int qca_serdev_probe(struct serdev_device *serdev)
* let's use the power sequencer. Otherwise, let's
* drive everything ourselves.
*/
- qcadev->bt_power->pwrseq = devm_pwrseq_get(&serdev->dev,
- "bluetooth");
+ qcadev->bt_power.pwrseq = devm_pwrseq_get(&serdev->dev,
+ "bluetooth");
/*
* Some modules have BT_EN enabled via a hardware pull-up,
@@ -2483,21 +2463,21 @@ static int qca_serdev_probe(struct serdev_device *serdev)
* 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;
+ if (IS_ERR(qcadev->bt_power.pwrseq))
+ qcadev->bt_power.pwrseq = NULL;
else
break;
}
- qcadev->bt_power->dev = &serdev->dev;
- err = qca_init_regulators(qcadev->bt_power, data->vregs,
+ qcadev->bt_power.dev = &serdev->dev;
+ err = qca_init_regulators(&qcadev->bt_power, data->vregs,
data->num_vregs);
if (err) {
BT_ERR("Failed to init regulators:%d", err);
return err;
}
- qcadev->bt_power->vregs_on = false;
+ qcadev->bt_power.vregs_on = false;
qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable",
GPIOD_OUT_LOW);
@@ -2531,10 +2511,10 @@ static int qca_serdev_probe(struct serdev_device *serdev)
case QCA_QCA6390:
if (dev_of_node(&serdev->dev)) {
- qcadev->bt_power->pwrseq = devm_pwrseq_get(&serdev->dev,
- "bluetooth");
- if (IS_ERR(qcadev->bt_power->pwrseq))
- return PTR_ERR(qcadev->bt_power->pwrseq);
+ qcadev->bt_power.pwrseq = devm_pwrseq_get(&serdev->dev,
+ "bluetooth");
+ if (IS_ERR(qcadev->bt_power.pwrseq))
+ return PTR_ERR(qcadev->bt_power.pwrseq);
break;
}
fallthrough;
@@ -2558,16 +2538,16 @@ static int qca_serdev_probe(struct serdev_device *serdev)
}
}
- if (qcadev->bt_power->pwrseq) {
- bt_en_available = pwrseq_is_controllable(qcadev->bt_power->pwrseq);
+ 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.
* The descriptor itself is still released by devres,
* so dropping the handle here is not a leak.
*/
- pwrseq_power_on(qcadev->bt_power->pwrseq);
- qcadev->bt_power->pwrseq = NULL;
+ pwrseq_enable(qcadev->bt_power.pwrseq);
+ qcadev->bt_power.pwrseq = NULL;
}
}
@@ -2605,7 +2585,7 @@ static int qca_serdev_probe(struct serdev_device *serdev)
static void qca_serdev_remove(struct serdev_device *serdev)
{
struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
- struct qca_power *power = qcadev->bt_power;
+ struct qca_power *power = &qcadev->bt_power;
switch (qcadev->btsoc_type) {
case QCA_WCN3988:
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v7 5/8] Bluetooth: hci_qca: Support QCA2066 on M.2 connector via pwrseq
2026-10-05 12:21 [PATCH v7 0/8] arm64: dts: monaco-arduino-monza: Add support for LGA WiFi/BT module Loic Poulain
` (3 preceding siblings ...)
2026-10-05 12:21 ` [PATCH v7 4/8] Bluetooth: hci_qca: Embed bt_power in struct qca_serdev Loic Poulain
@ 2026-10-05 12:21 ` Loic Poulain
2026-10-05 12:33 ` sashiko-bot
2026-10-07 22:57 ` Val Packett
2026-10-05 12:21 ` [PATCH v7 6/8] Bluetooth: hci_qca: Flatten struct qca_power into struct qca_serdev Loic Poulain
` (2 subsequent siblings)
7 siblings, 2 replies; 24+ messages in thread
From: Loic Poulain @ 2026-10-05 12:21 UTC (permalink / raw)
To: Manivannan Sadhasivam, Bartosz Golaszewski, Marcel Holtmann,
Luiz Augusto von Dentz, Bjorn Andersson, Konrad Dybcio,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pci, linux-pm, linux-kernel, linux-arm-msm, linux-bluetooth,
devicetree, Manivannan Sadhasivam, Loic Poulain, Dmitry Baryshkov,
Bartosz Golaszewski
For QCA2066 (and other QCA chips) on M.2 connectors, the UART enable is
controlled by the W_DISABLE2# signal managed by the pcie-m2 power sequencer
rather than a dedicated BT enable GPIO.
When the serdev controller has an OF graph (indicating it is connected to
an M.2 connector), acquire the 'uart' pwrseq target from the connector's
power sequencer and use it to control BT power instead of the bt-enable
GPIO. This is factored out into qca_serdev_get_m2_pwrseq().
Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
---
drivers/bluetooth/hci_qca.c | 47 +++++++++++++++++++++++++++++++++++----------
1 file changed, 37 insertions(+), 10 deletions(-)
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 1d27ff98034ba99d0783e48db5c605f3b31117ea..b6ec1a57248e2cf4bd138898ffc5cad45b1b4a8b 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -1875,6 +1875,9 @@ static int qca_power_on(struct hci_dev *hdev)
/* Controller needs time to bootup. */
msleep(150);
}
+
+ if (qcadev->bt_power.pwrseq)
+ pwrseq_power_on(qcadev->bt_power.pwrseq);
}
clear_bit(QCA_BT_OFF, &qca->flags);
@@ -2396,6 +2399,34 @@ static int qca_init_regulators(struct qca_power *qca,
return 0;
}
+static void qca_serdev_put_pwrseq(void *data)
+{
+ pwrseq_put(data);
+}
+
+static int qca_serdev_get_m2_pwrseq(struct qca_serdev *qcadev)
+{
+ struct serdev_device *serdev = qcadev->serdev_hu.serdev;
+ struct pwrseq_desc *pwrseq;
+
+ if (!of_graph_is_present(dev_of_node(&serdev->ctrl->dev)))
+ return 0;
+
+ /* The pwrseq is looked up on the serdev controller (which holds the
+ * OF graph to the M.2 connector), but its lifetime must follow this
+ * serdev consumer device, not the controller. So acquire it with the
+ * non-devres pwrseq_get() and release it via a devres action bound to
+ * &serdev->dev instead of using devm_pwrseq_get(&serdev->ctrl->dev).
+ */
+ pwrseq = pwrseq_get(&serdev->ctrl->dev, "uart");
+ if (IS_ERR(pwrseq))
+ return PTR_ERR(pwrseq);
+
+ qcadev->bt_power.pwrseq = pwrseq;
+
+ return devm_add_action_or_reset(&serdev->dev, qca_serdev_put_pwrseq, pwrseq);
+}
+
static int qca_serdev_probe(struct serdev_device *serdev)
{
struct qca_serdev *qcadev;
@@ -2426,6 +2457,10 @@ static int qca_serdev_probe(struct serdev_device *serdev)
else
qcadev->btsoc_type = QCA_ROME;
+ err = qca_serdev_get_m2_pwrseq(qcadev);
+ if (err)
+ return err;
+
switch (qcadev->btsoc_type) {
case QCA_WCN3950:
case QCA_WCN3988:
@@ -2435,17 +2470,9 @@ static int qca_serdev_probe(struct serdev_device *serdev)
case QCA_WCN6750:
case QCA_WCN6855:
case QCA_WCN7850:
- /*
- * OF graph link is only present for BT devices attached through
- * the M.2 Key E connector.
- */
- if (of_graph_is_present(dev_of_node(&serdev->ctrl->dev))) {
- qcadev->bt_power.pwrseq = devm_pwrseq_get(&serdev->ctrl->dev,
- "uart");
- if (IS_ERR(qcadev->bt_power.pwrseq))
- return PTR_ERR(qcadev->bt_power.pwrseq);
+ /* M.2 connector modules are powered by the pwrseq acquired above. */
+ if (qcadev->bt_power.pwrseq)
break;
- }
if (!device_property_present(&serdev->dev, "enable-gpios")) {
/*
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: [PATCH v7 5/8] Bluetooth: hci_qca: Support QCA2066 on M.2 connector via pwrseq
2026-10-05 12:21 ` [PATCH v7 5/8] Bluetooth: hci_qca: Support QCA2066 on M.2 connector via pwrseq Loic Poulain
@ 2026-10-05 12:33 ` sashiko-bot
2026-10-07 22:57 ` Val Packett
1 sibling, 0 replies; 24+ messages in thread
From: sashiko-bot @ 2026-10-05 12:33 UTC (permalink / raw)
To: Loic Poulain; +Cc: devicetree, conor+dt, linux-pci, robh
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] hci_qca: QCA6390 probe fails on M.2 connectors due to overwritten pwrseq
- [Medium] hci_qca: missing error check for power sequencer enable in qca_power_on()
- [Medium] hci_qca: asymmetric power-off leaks bt_en GPIO assertion
--
commit d33d72433b2dc1cfeaa1bb5a87c7d716233a54a5
Author: Loic Poulain <loic.poulain@oss.qualcomm.com>
Bluetooth: hci_qca: Support QCA2066 on M.2 connector via pwrseq
This patch modifies the QCA HCI driver to support QCA2066 (and similar chips)
on M.2 connectors. It updates the probe sequence to acquire a power sequencer
for the M.2 UART connection instead of relying on a dedicated BT enable GPIO.
> diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
> index 1d27ff98034ba..b6ec1a57248e2 100644
> --- a/drivers/bluetooth/hci_qca.c
> +++ b/drivers/bluetooth/hci_qca.c
> @@ -1875,6 +1875,9 @@ static int qca_power_on(struct hci_dev *hdev)
> /* Controller needs time to bootup. */
> msleep(150);
> }
> +
> + if (qcadev->bt_power.pwrseq)
> + pwrseq_power_on(qcadev->bt_power.pwrseq);
> }
[Severity: Medium]
Does this code need to check the return value of pwrseq_power_on()?
If the power sequencer API returns an error (for example, due to a regulator
error or timeout), the result is discarded and the driver will incorrectly
assume power-on succeeded.
This causes the driver to attempt communication with an unpowered Bluetooth
controller, leading to HCI command timeouts and driver malfunction.
[ ... ]
> @@ -2426,6 +2457,10 @@ static int qca_serdev_probe(struct serdev_device *serdev)
> else
> qcadev->btsoc_type = QCA_ROME;
>
> + err = qca_serdev_get_m2_pwrseq(qcadev);
> + if (err)
> + return err;
> +
[Severity: High]
Does this code overwrite the M.2 power sequencer and break probe for
QCA6390 chips?
Because qca_serdev_get_m2_pwrseq() is now called unconditionally for all
chips before the switch statement, it correctly acquires the M.2 power
sequencer when present. However, the QCA_QCA6390 branch further down in
this function lacks a guard to prevent overwriting it:
case QCA_QCA6390:
if (dev_of_node(&serdev->dev)) {
qcadev->bt_power.pwrseq = devm_pwrseq_get(&serdev->dev,
"bluetooth");
if (IS_ERR(qcadev->bt_power.pwrseq))
return PTR_ERR(qcadev->bt_power.pwrseq);
break;
}
If the serdev has an OF node, this overwrites the M.2 power sequencer
with a request for a 'bluetooth' power sequencer. This fails with -ENOENT
and aborts the probe.
[Severity: Medium]
Can this early acquisition cause an asymmetric power-off that leaks the bt_en
GPIO assertion?
For legacy/default SoC types (like QCA_ROME), the default branch of the
switch statement doesn't check if the power sequencer was already acquired:
default:
qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable",
GPIOD_OUT_LOW);
If both exist, qca_power_on() asserts the bt_en GPIO and enables the power
sequencer. However, qca_power_off() disables the power sequencer and
immediately returns:
if (power->pwrseq) {
pwrseq_disable(power->pwrseq);
set_bit(QCA_BT_OFF, &qca->flags);
return;
}
This early return bypasses the fallback logic that de-asserts bt_en, leaving
the hardware partially enabled.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261005-monza-wireless-v7-0-5a6de7662dcb@oss.qualcomm.com?part=5
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: [PATCH v7 5/8] Bluetooth: hci_qca: Support QCA2066 on M.2 connector via pwrseq
2026-10-05 12:21 ` [PATCH v7 5/8] Bluetooth: hci_qca: Support QCA2066 on M.2 connector via pwrseq Loic Poulain
2026-10-05 12:33 ` sashiko-bot
@ 2026-10-07 22:57 ` Val Packett
1 sibling, 0 replies; 24+ messages in thread
From: Val Packett @ 2026-10-07 22:57 UTC (permalink / raw)
To: Loic Poulain, Manivannan Sadhasivam, Bartosz Golaszewski,
Marcel Holtmann, Luiz Augusto von Dentz, Bjorn Andersson,
Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pci, linux-pm, linux-kernel, linux-arm-msm, linux-bluetooth,
devicetree, Manivannan Sadhasivam, Dmitry Baryshkov,
Bartosz Golaszewski
On 10/5/26 9:21 AM, Loic Poulain wrote:
> For QCA2066 (and other QCA chips) on M.2 connectors, the UART enable is
> controlled by the W_DISABLE2# signal managed by the pcie-m2 power sequencer
> rather than a dedicated BT enable GPIO.
>
> When the serdev controller has an OF graph (indicating it is connected to
> an M.2 connector), acquire the 'uart' pwrseq target from the connector's
> power sequencer and use it to control BT power instead of the bt-enable
> GPIO. This is factored out into qca_serdev_get_m2_pwrseq().
>
> Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
> Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
> ---
> drivers/bluetooth/hci_qca.c | 47 +++++++++++++++++++++++++++++++++++----------
> 1 file changed, 37 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
> index 1d27ff98034ba99d0783e48db5c605f3b31117ea..b6ec1a57248e2cf4bd138898ffc5cad45b1b4a8b 100644
> --- a/drivers/bluetooth/hci_qca.c
> +++ b/drivers/bluetooth/hci_qca.c
> @@ -1875,6 +1875,9 @@ static int qca_power_on(struct hci_dev *hdev)
> /* Controller needs time to bootup. */
> msleep(150);
> }
> +
> + if (qcadev->bt_power.pwrseq)
> + pwrseq_power_on(qcadev->bt_power.pwrseq);
> }
>
> clear_bit(QCA_BT_OFF, &qca->flags);
> @@ -2396,6 +2399,34 @@ static int qca_init_regulators(struct qca_power *qca,
> return 0;
> }
>
> +static void qca_serdev_put_pwrseq(void *data)
> +{
> + pwrseq_put(data);
> +}
> +
> +static int qca_serdev_get_m2_pwrseq(struct qca_serdev *qcadev)
> +{
> + struct serdev_device *serdev = qcadev->serdev_hu.serdev;
> + struct pwrseq_desc *pwrseq;
> +
> + if (!of_graph_is_present(dev_of_node(&serdev->ctrl->dev)))
> + return 0;
Seems like of_graph_is_present does *not* return false for the existing
(non-connector) setup which is currently used in all the laptop device
trees..
> +
> + /* The pwrseq is looked up on the serdev controller (which holds the
> + * OF graph to the M.2 connector), but its lifetime must follow this
> + * serdev consumer device, not the controller. So acquire it with the
> + * non-devres pwrseq_get() and release it via a devres action bound to
> + * &serdev->dev instead of using devm_pwrseq_get(&serdev->ctrl->dev).
> + */
> + pwrseq = pwrseq_get(&serdev->ctrl->dev, "uart");
> + if (IS_ERR(pwrseq))
> + return PTR_ERR(pwrseq);
> [..]
So this returns EPROBE_DEFER and bluetooth gets deferred forever :(
~val
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v7 6/8] Bluetooth: hci_qca: Flatten struct qca_power into struct qca_serdev
2026-10-05 12:21 [PATCH v7 0/8] arm64: dts: monaco-arduino-monza: Add support for LGA WiFi/BT module Loic Poulain
` (4 preceding siblings ...)
2026-10-05 12:21 ` [PATCH v7 5/8] Bluetooth: hci_qca: Support QCA2066 on M.2 connector via pwrseq Loic Poulain
@ 2026-10-05 12:21 ` Loic Poulain
2026-10-05 12:29 ` sashiko-bot
2026-10-05 12:21 ` [PATCH v7 7/8] dt-bindings: connector: pcie-m2-e: Add vendor LGA connector compatible Loic Poulain
2026-10-05 12:21 ` [PATCH v7 8/8] arm64: dts: qcom: monaco-arduino-monza: Add QCA2066 M.2 WiFi/BT support Loic Poulain
7 siblings, 1 reply; 24+ messages in thread
From: Loic Poulain @ 2026-10-05 12:21 UTC (permalink / raw)
To: Manivannan Sadhasivam, Bartosz Golaszewski, Marcel Holtmann,
Luiz Augusto von Dentz, Bjorn Andersson, Konrad Dybcio,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pci, linux-pm, linux-kernel, linux-arm-msm, linux-bluetooth,
devicetree, Manivannan Sadhasivam, Loic Poulain, Dmitry Baryshkov
struct qca_power currently only groups a handful of fields
(vreg_bulk, num_vregs, vregs_on, pwrseq) that are exclusively used
from struct qca_serdev, via its embedded bt_power member. The extra
indirection level does not provide any isolation or reuse benefit,
and just adds qcadev->bt_power.<field> noise throughout the driver.
Drop struct qca_power and move its fields directly into
struct qca_serdev, updating qca_init_regulators() to take a
struct qca_serdev pointer instead. No functional change intended.
Suggested-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
---
drivers/bluetooth/hci_qca.c | 91 +++++++++++++++++++--------------------------
1 file changed, 39 insertions(+), 52 deletions(-)
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index b6ec1a57248e2cf4bd138898ffc5cad45b1b4a8b..55a3b6c1c2ce7cdfa9e2d55a7ab97298d69b0057 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -211,21 +211,16 @@ struct qca_device_data {
/*
* Platform data for the QCA Bluetooth power driver.
*/
-struct qca_power {
- struct device *dev;
- struct regulator_bulk_data *vreg_bulk;
- int num_vregs;
- bool vregs_on;
- struct pwrseq_desc *pwrseq;
-};
-
struct qca_serdev {
struct hci_uart serdev_hu;
struct gpio_desc *bt_en;
struct gpio_desc *sw_ctrl;
struct clk *susclk;
enum qca_btsoc_type btsoc_type;
- struct qca_power bt_power;
+ struct regulator_bulk_data *vreg_bulk;
+ int num_vregs;
+ bool vregs_on;
+ struct pwrseq_desc *pwrseq;
u32 init_speed;
u32 oper_speed;
bool bdaddr_property_broken;
@@ -1779,7 +1774,7 @@ static int qca_regulator_init(struct hci_uart *hu)
*/
qcadev = serdev_device_get_drvdata(hu->serdev);
- if (!qcadev->bt_power.vregs_on) {
+ if (!qcadev->vregs_on) {
serdev_device_close(hu->serdev);
ret = qca_regulator_enable(qcadev);
if (ret)
@@ -1876,8 +1871,8 @@ static int qca_power_on(struct hci_dev *hdev)
msleep(150);
}
- if (qcadev->bt_power.pwrseq)
- pwrseq_power_on(qcadev->bt_power.pwrseq);
+ if (qcadev->pwrseq)
+ pwrseq_enable(qcadev->pwrseq);
}
clear_bit(QCA_BT_OFF, &qca->flags);
@@ -2230,7 +2225,6 @@ static void qca_power_off(struct hci_uart *hu)
unsigned long flags;
enum qca_btsoc_type soc_type = qca_soc_type(hu);
bool sw_ctrl_state;
- struct qca_power *power;
/* From this point we go into power off state. But serial port may
* still be open, stop queueing the IBS data and flush all the buffered
@@ -2248,7 +2242,6 @@ static void qca_power_off(struct hci_uart *hu)
return;
qcadev = serdev_device_get_drvdata(hu->serdev);
- power = &qcadev->bt_power;
switch (soc_type) {
case QCA_WCN3988:
@@ -2268,8 +2261,8 @@ static void qca_power_off(struct hci_uart *hu)
break;
}
- if (power->pwrseq) {
- pwrseq_disable(power->pwrseq);
+ if (qcadev->pwrseq) {
+ pwrseq_disable(qcadev->pwrseq);
set_bit(QCA_BT_OFF, &qca->flags);
return;
}
@@ -2325,23 +2318,22 @@ static int qca_hci_shutdown(struct hci_dev *hdev)
static int qca_regulator_enable(struct qca_serdev *qcadev)
{
- struct qca_power *power = &qcadev->bt_power;
int ret;
- if (power->pwrseq)
- return pwrseq_enable(power->pwrseq);
+ if (qcadev->pwrseq)
+ return pwrseq_enable(qcadev->pwrseq);
/* Already enabled */
- if (power->vregs_on)
+ if (qcadev->vregs_on)
return 0;
- BT_DBG("enabling %d regulators)", power->num_vregs);
+ BT_DBG("enabling %d regulators)", qcadev->num_vregs);
- ret = regulator_bulk_enable(power->num_vregs, power->vreg_bulk);
+ ret = regulator_bulk_enable(qcadev->num_vregs, qcadev->vreg_bulk);
if (ret)
return ret;
- power->vregs_on = true;
+ qcadev->vregs_on = true;
ret = clk_prepare_enable(qcadev->susclk);
if (ret)
@@ -2352,38 +2344,35 @@ static int qca_regulator_enable(struct qca_serdev *qcadev)
static void qca_regulator_disable(struct qca_serdev *qcadev)
{
- struct qca_power *power;
-
if (!qcadev)
return;
- power = &qcadev->bt_power;
-
/* Already disabled? */
- if (!power->vregs_on)
+ if (!qcadev->vregs_on)
return;
- regulator_bulk_disable(power->num_vregs, power->vreg_bulk);
- power->vregs_on = false;
+ regulator_bulk_disable(qcadev->num_vregs, qcadev->vreg_bulk);
+ qcadev->vregs_on = false;
clk_disable_unprepare(qcadev->susclk);
}
-static int qca_init_regulators(struct qca_power *qca,
+static int qca_init_regulators(struct qca_serdev *qcadev,
const struct qca_vreg *vregs, size_t num_vregs)
{
+ struct device *dev = &qcadev->serdev_hu.serdev->dev;
struct regulator_bulk_data *bulk;
int ret;
int i;
- bulk = devm_kcalloc(qca->dev, num_vregs, sizeof(*bulk), GFP_KERNEL);
+ bulk = devm_kcalloc(dev, num_vregs, sizeof(*bulk), GFP_KERNEL);
if (!bulk)
return -ENOMEM;
for (i = 0; i < num_vregs; i++)
bulk[i].supply = vregs[i].name;
- ret = devm_regulator_bulk_get(qca->dev, num_vregs, bulk);
+ ret = devm_regulator_bulk_get(dev, num_vregs, bulk);
if (ret < 0)
return ret;
@@ -2393,8 +2382,8 @@ static int qca_init_regulators(struct qca_power *qca,
return ret;
}
- qca->vreg_bulk = bulk;
- qca->num_vregs = num_vregs;
+ qcadev->vreg_bulk = bulk;
+ qcadev->num_vregs = num_vregs;
return 0;
}
@@ -2422,7 +2411,7 @@ static int qca_serdev_get_m2_pwrseq(struct qca_serdev *qcadev)
if (IS_ERR(pwrseq))
return PTR_ERR(pwrseq);
- qcadev->bt_power.pwrseq = pwrseq;
+ qcadev->pwrseq = pwrseq;
return devm_add_action_or_reset(&serdev->dev, qca_serdev_put_pwrseq, pwrseq);
}
@@ -2471,7 +2460,7 @@ static int qca_serdev_probe(struct serdev_device *serdev)
case QCA_WCN6855:
case QCA_WCN7850:
/* M.2 connector modules are powered by the pwrseq acquired above. */
- if (qcadev->bt_power.pwrseq)
+ if (qcadev->pwrseq)
break;
if (!device_property_present(&serdev->dev, "enable-gpios")) {
@@ -2481,7 +2470,7 @@ static int qca_serdev_probe(struct serdev_device *serdev)
* let's use the power sequencer. Otherwise, let's
* drive everything ourselves.
*/
- qcadev->bt_power.pwrseq = devm_pwrseq_get(&serdev->dev,
+ qcadev->pwrseq = devm_pwrseq_get(&serdev->dev,
"bluetooth");
/*
@@ -2490,21 +2479,20 @@ static int qca_serdev_probe(struct serdev_device *serdev)
* 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;
+ if (IS_ERR(qcadev->pwrseq))
+ qcadev->pwrseq = NULL;
else
break;
}
- qcadev->bt_power.dev = &serdev->dev;
- err = qca_init_regulators(&qcadev->bt_power, data->vregs,
+ err = qca_init_regulators(qcadev, data->vregs,
data->num_vregs);
if (err) {
BT_ERR("Failed to init regulators:%d", err);
return err;
}
- qcadev->bt_power.vregs_on = false;
+ qcadev->vregs_on = false;
qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable",
GPIOD_OUT_LOW);
@@ -2538,10 +2526,10 @@ static int qca_serdev_probe(struct serdev_device *serdev)
case QCA_QCA6390:
if (dev_of_node(&serdev->dev)) {
- qcadev->bt_power.pwrseq = devm_pwrseq_get(&serdev->dev,
+ qcadev->pwrseq = devm_pwrseq_get(&serdev->dev,
"bluetooth");
- if (IS_ERR(qcadev->bt_power.pwrseq))
- return PTR_ERR(qcadev->bt_power.pwrseq);
+ if (IS_ERR(qcadev->pwrseq))
+ return PTR_ERR(qcadev->pwrseq);
break;
}
fallthrough;
@@ -2565,16 +2553,16 @@ static int qca_serdev_probe(struct serdev_device *serdev)
}
}
- if (qcadev->bt_power.pwrseq) {
- bt_en_available = pwrseq_is_controllable(qcadev->bt_power.pwrseq);
+ if (qcadev->pwrseq) {
+ bt_en_available = pwrseq_is_controllable(qcadev->pwrseq);
if (!bt_en_available) {
/* The host cannot gate the BT power individually.
* Treat it as always-on and drop the pwrseq handle.
* The descriptor itself is still released by devres,
* so dropping the handle here is not a leak.
*/
- pwrseq_enable(qcadev->bt_power.pwrseq);
- qcadev->bt_power.pwrseq = NULL;
+ pwrseq_enable(qcadev->pwrseq);
+ qcadev->pwrseq = NULL;
}
}
@@ -2612,7 +2600,6 @@ static int qca_serdev_probe(struct serdev_device *serdev)
static void qca_serdev_remove(struct serdev_device *serdev)
{
struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
- struct qca_power *power = &qcadev->bt_power;
switch (qcadev->btsoc_type) {
case QCA_WCN3988:
@@ -2622,7 +2609,7 @@ static void qca_serdev_remove(struct serdev_device *serdev)
case QCA_WCN6750:
case QCA_WCN6855:
case QCA_WCN7850:
- if (power->vregs_on)
+ if (qcadev->vregs_on)
qca_power_off(&qcadev->serdev_hu);
break;
default:
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: [PATCH v7 6/8] Bluetooth: hci_qca: Flatten struct qca_power into struct qca_serdev
2026-10-05 12:21 ` [PATCH v7 6/8] Bluetooth: hci_qca: Flatten struct qca_power into struct qca_serdev Loic Poulain
@ 2026-10-05 12:29 ` sashiko-bot
0 siblings, 0 replies; 24+ messages in thread
From: sashiko-bot @ 2026-10-05 12:29 UTC (permalink / raw)
To: Loic Poulain; +Cc: devicetree, linux-pci, conor+dt, robh
> struct qca_power currently only groups a handful of fields
> (vreg_bulk, num_vregs, vregs_on, pwrseq) that are exclusively used
> from struct qca_serdev, via its embedded bt_power member. The extra
> indirection level does not provide any isolation or reuse benefit,
> and just adds qcadev->bt_power.<field> noise throughout the driver.
>
> Drop struct qca_power and move its fields directly into
> struct qca_serdev, updating qca_init_regulators() to take a
> struct qca_serdev pointer instead. No functional change intended.
>
> Suggested-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261005-monza-wireless-v7-0-5a6de7662dcb@oss.qualcomm.com?part=6
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v7 7/8] dt-bindings: connector: pcie-m2-e: Add vendor LGA connector compatible
2026-10-05 12:21 [PATCH v7 0/8] arm64: dts: monaco-arduino-monza: Add support for LGA WiFi/BT module Loic Poulain
` (5 preceding siblings ...)
2026-10-05 12:21 ` [PATCH v7 6/8] Bluetooth: hci_qca: Flatten struct qca_power into struct qca_serdev Loic Poulain
@ 2026-10-05 12:21 ` Loic Poulain
2026-10-05 12:23 ` sashiko-bot
2026-10-05 12:21 ` [PATCH v7 8/8] arm64: dts: qcom: monaco-arduino-monza: Add QCA2066 M.2 WiFi/BT support Loic Poulain
7 siblings, 1 reply; 24+ messages in thread
From: Loic Poulain @ 2026-10-05 12:21 UTC (permalink / raw)
To: Manivannan Sadhasivam, Bartosz Golaszewski, Marcel Holtmann,
Luiz Augusto von Dentz, Bjorn Andersson, Konrad Dybcio,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pci, linux-pm, linux-kernel, linux-arm-msm, linux-bluetooth,
devicetree, Manivannan Sadhasivam, Loic Poulain,
Krzysztof Kozlowski, Bartosz Golaszewski
Some modules (e.g. the Qualcomm QCA2066/QCNFA765) expose the same M.2
Key E interface signals but are physically soldered as an LGA package
rather than plugged into a real M.2 Key E connector socket. Such designs
are not actual M.2 Key E connectors, so describe them with a dedicated
vendor-specific compatible while keeping "pcie-m2-e-connector" as a
fallback for the shared signal semantics.
Add "qcom,pcie-m2-1418-lga-connector" for the M.2 LGA 1418 found on
Arduino Ventuno Q (Monaco Monza).
Add "qcom,pcie-m2-1620-lga-connector" for the M.2 LGA 1620 found on
The Lenovo Thinkpad T14s.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
---
.../devicetree/bindings/connector/pcie-m2-e-connector.yaml | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml b/Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml
index f7859aa9b63469cb43919c0b5719c18694c5364d..ce6173a0ec41cfe8ab4a5780940999c18674ab7e 100644
--- a/Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml
+++ b/Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml
@@ -17,7 +17,13 @@ description:
properties:
compatible:
- const: pcie-m2-e-connector
+ oneOf:
+ - const: pcie-m2-e-connector
+ - items:
+ - enum:
+ - qcom,pcie-m2-1418-lga-connector
+ - qcom,pcie-m2-1620-lga-connector
+ - const: pcie-m2-e-connector
vpcie3v3-supply:
description: A phandle to the regulator for 3.3v supply.
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v7 8/8] arm64: dts: qcom: monaco-arduino-monza: Add QCA2066 M.2 WiFi/BT support
2026-10-05 12:21 [PATCH v7 0/8] arm64: dts: monaco-arduino-monza: Add support for LGA WiFi/BT module Loic Poulain
` (6 preceding siblings ...)
2026-10-05 12:21 ` [PATCH v7 7/8] dt-bindings: connector: pcie-m2-e: Add vendor LGA connector compatible Loic Poulain
@ 2026-10-05 12:21 ` Loic Poulain
2026-10-05 12:37 ` sashiko-bot
7 siblings, 1 reply; 24+ messages in thread
From: Loic Poulain @ 2026-10-05 12:21 UTC (permalink / raw)
To: Manivannan Sadhasivam, Bartosz Golaszewski, Marcel Holtmann,
Luiz Augusto von Dentz, Bjorn Andersson, Konrad Dybcio,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pci, linux-pm, linux-kernel, linux-arm-msm, linux-bluetooth,
devicetree, Manivannan Sadhasivam, Loic Poulain, Konrad Dybcio,
Dmitry Baryshkov, Bartosz Golaszewski
Add support for the QCA2066 (QCNFA765) WiFi/Bluetooth module on the
Arduino VENTUNO Q board. The module is interfaced via LGA and is
compatible with the M.2 Key E.
Add wireless-lga-connector node using pcie-m2-e-connector binding,
connecting PCIe port 0 to the WiFi interface and UART10 port 3 to
the Bluetooth interface.
Add pcie@1,0 downstream port node with pciclass,0604 compatible so
the pci-pwrctrl driver can acquire the power sequencer and enable
the M.2 slot before PCIe enumeration.
Add nfa725b_default_state pinctrl for the W_DISABLE1/2 GPIOs
(gpio56/gpio55) used by the power sequencer.
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/monaco-arduino-monza.dts | 64 +++++++++++++++++++++--
1 file changed, 60 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/monaco-arduino-monza.dts b/arch/arm64/boot/dts/qcom/monaco-arduino-monza.dts
index 940a03732eefc49280b4182101cf3fb9ee951053..f24a87bd7cbf63bda803161f3659b0538a5ee35a 100644
--- a/arch/arm64/boot/dts/qcom/monaco-arduino-monza.dts
+++ b/arch/arm64/boot/dts/qcom/monaco-arduino-monza.dts
@@ -178,6 +178,40 @@ vreg_nvme: regulator-3p3-m2 {
enable-active-high;
startup-delay-us = <20000>;
};
+
+ wireless-lga-connector {
+ compatible = "qcom,pcie-m2-1418-lga-connector",
+ "pcie-m2-e-connector";
+ vpcie3v3-supply = <&vdc_3v3>;
+ vpcie1v8-supply = <&vdc_1v8>;
+ w-disable1-gpios = <&tlmm 56 GPIO_ACTIVE_LOW>;
+ w-disable2-gpios = <&tlmm 55 GPIO_ACTIVE_LOW>;
+ pinctrl-0 = <&nfa725b_default_state>;
+ pinctrl-names = "default";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* WiFi/PCIe */
+ port@0 {
+ reg = <0>;
+
+ lga_pcie_ep: endpoint {
+ remote-endpoint = <&pcie_ep>;
+ };
+ };
+
+ /* Bluetooth/UART */
+ port@3 {
+ reg = <3>;
+
+ lga_uart_ep: endpoint {
+ remote-endpoint = <&uart10_ep>;
+ };
+ };
+ };
+ };
};
&cci1 {
@@ -541,6 +575,22 @@ pcie@0,0 {
ranges;
reg = <0x010000 0x00 0x00 0x00 0x00>;
+ pcie@1,0 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ compatible = "pciclass,0604";
+ bus-range = <0x00 0xff>;
+ ranges;
+ reg = <0x020800 0x00 0x00 0x00 0x00>;
+
+ port {
+ pcie_ep: endpoint {
+ remote-endpoint = <&lga_pcie_ep>;
+ };
+ };
+ };
+
pcie@2,0 {
#address-cells = <3>;
#size-cells = <2>;
@@ -694,6 +744,12 @@ max98091_default: max98091-default-state {
bias-pull-up;
};
+ nfa725b_default_state: nfa725b-default-state {
+ pins = "gpio55", "gpio56";
+ function = "gpio";
+ bias-disable;
+ };
+
pcie1_default_state: pcie1-default-state {
wake-pins {
pins = "gpio21";
@@ -745,10 +801,10 @@ &uart7 {
&uart10 {
status = "okay";
- bluetooth: bluetooth {
- compatible = "qcom,qca2066-bt";
- enable-gpios = <&tlmm 55 GPIO_ACTIVE_HIGH>;
- clocks = <&sleep_clk>;
+ port {
+ uart10_ep: endpoint {
+ remote-endpoint = <&lga_uart_ep>;
+ };
};
};
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: [PATCH v7 8/8] arm64: dts: qcom: monaco-arduino-monza: Add QCA2066 M.2 WiFi/BT support
2026-10-05 12:21 ` [PATCH v7 8/8] arm64: dts: qcom: monaco-arduino-monza: Add QCA2066 M.2 WiFi/BT support Loic Poulain
@ 2026-10-05 12:37 ` sashiko-bot
0 siblings, 0 replies; 24+ messages in thread
From: sashiko-bot @ 2026-10-05 12:37 UTC (permalink / raw)
To: Loic Poulain; +Cc: devicetree, conor+dt, linux-pci, robh
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Low] dts: qcom: missing clocks property in wireless-lga-connector
- [Low] dts: qcom: invalid bus-range property for downstream PCI bridge
--
commit 29a5722958bd298370461ff6846d50f2a2e13fa0
Author: Loic Poulain <loic.poulain@oss.qualcomm.com>
arm64: dts: qcom: monaco-arduino-monza: Add QCA2066 M.2 WiFi/BT support
This commit adds support for the QCA2066 WiFi/Bluetooth module on the
Arduino VENTUNO Q board. It introduces a wireless-lga-connector node and a
downstream pcie port to enable the M.2 slot power sequencer.
> diff --git a/arch/arm64/boot/dts/qcom/monaco-arduino-monza.dts b/arch/arm64/boot/dts/qcom/monaco-arduino-monza.dts
> index 940a03732eefc..f24a87bd7cbf6 100644
> --- a/arch/arm64/boot/dts/qcom/monaco-arduino-monza.dts
> +++ b/arch/arm64/boot/dts/qcom/monaco-arduino-monza.dts
> @@ -178,6 +178,40 @@ vreg_nvme: regulator-3p3-m2 {
> enable-active-high;
> startup-delay-us = <20000>;
> };
> +
> + wireless-lga-connector {
> + compatible = "qcom,pcie-m2-1418-lga-connector",
> + "pcie-m2-e-connector";
> + vpcie3v3-supply = <&vdc_3v3>;
> + vpcie1v8-supply = <&vdc_1v8>;
> + w-disable1-gpios = <&tlmm 56 GPIO_ACTIVE_LOW>;
> + w-disable2-gpios = <&tlmm 55 GPIO_ACTIVE_LOW>;
[Severity: Low]
Is the clocks property missing here in the wireless-lga-connector node for
the M.2 SUSCLK routing?
The clocks property is defined in the pcie-m2-e-connector binding and was
previously included in the legacy bluetooth node, but appears to have been
dropped during the transition to the new node. Because sleep_clk is a fixed
clock that is physically always running on this platform, the omission causes
no functional regression, but the Device Tree hardware description seems
incomplete without the SUSCLK routing.
[ ... ]
> @@ -541,6 +575,22 @@ pcie@0,0 {
> ranges;
> reg = <0x010000 0x00 0x00 0x00 0x00>;
>
> + pcie@1,0 {
> + #address-cells = <3>;
> + #size-cells = <2>;
> + device_type = "pci";
> + compatible = "pciclass,0604";
> + bus-range = <0x00 0xff>;
[Severity: Low]
Does this bus-range property in the pcie@1,0 node define an invalid
secondary bus?
The bus-range property claims the downstream bridge's secondary bus is 0,
which violates PCI numbering rules since its primary bus is 2 (encoded in
the reg property as 0x020800).
The Linux PCI core dynamically reassigns invalid topologies for downstream
bridges, preventing functional breakage. However, specifying a topologically
invalid bus range in the DT seems to be an error.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261005-monza-wireless-v7-0-5a6de7662dcb@oss.qualcomm.com?part=8
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v6 01/11] Bluetooth: hci_qca: Add M.2 Bluetooth device support using pwrseq
@ 2026-09-04 15:42 Loic Poulain
2026-09-04 17:21 ` arm64: dts: monaco-arduino-monza: Add support for LGA WiFi/BT module bluez.test.bot
0 siblings, 1 reply; 24+ messages in thread
From: Loic Poulain @ 2026-09-04 15:42 UTC (permalink / raw)
To: Manivannan Sadhasivam, Bartosz Golaszewski, Marcel Holtmann,
Luiz Augusto von Dentz, Bjorn Andersson, Konrad Dybcio,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pci, linux-pm, linux-kernel, linux-arm-msm, linux-bluetooth,
devicetree, Manivannan Sadhasivam, Loic Poulain,
Bartosz Golaszewski, Dmitry Baryshkov, Wei Deng
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Power supply to the M.2 Bluetooth device attached to the host using M.2
connector is controlled using the 'uart' pwrseq device. So add support for
getting the pwrseq device if the OF graph link is present. Once obtained,
the existing pwrseq APIs can be used to control the power supplies of the
M.2 card.
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Tested-by: Wei Deng <wei.deng@oss.qualcomm.com>
---
drivers/bluetooth/hci_qca.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index faa964735adb17a05f2a8fac16f553b37b96020b..c8ea5507bdc2c83f214e3154b5ad6d05f418a1d4 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -25,6 +25,7 @@
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_graph.h>
#include <linux/acpi.h>
#include <linux/platform_device.h>
#include <linux/pwrseq/consumer.h>
@@ -2448,6 +2449,18 @@ static int qca_serdev_probe(struct serdev_device *serdev)
case QCA_WCN6750:
case QCA_WCN6855:
case QCA_WCN7850:
+ /*
+ * OF graph link is only present for BT devices attached through
+ * the M.2 Key E connector.
+ */
+ if (of_graph_is_present(dev_of_node(&serdev->ctrl->dev))) {
+ qcadev->bt_power->pwrseq = devm_pwrseq_get(&serdev->ctrl->dev,
+ "uart");
+ if (IS_ERR(qcadev->bt_power->pwrseq))
+ return PTR_ERR(qcadev->bt_power->pwrseq);
+ break;
+ }
+
if (!device_property_present(&serdev->dev, "enable-gpios")) {
/*
* Backward compatibility with old DT sources. If the
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v5 01/11] Bluetooth: hci_qca: Add M.2 Bluetooth device support using pwrseq
@ 2026-07-20 8:04 Loic Poulain
2026-07-20 9:51 ` arm64: dts: monaco-arduino-monza: Add support for LGA WiFi/BT module bluez.test.bot
0 siblings, 1 reply; 24+ messages in thread
From: Loic Poulain @ 2026-07-20 8:04 UTC (permalink / raw)
To: Manivannan Sadhasivam, Bartosz Golaszewski, Marcel Holtmann,
Luiz Augusto von Dentz, Bjorn Andersson, Konrad Dybcio,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pci, linux-pm, linux-kernel, linux-arm-msm, linux-bluetooth,
devicetree, Manivannan Sadhasivam, Loic Poulain,
Bartosz Golaszewski, Dmitry Baryshkov, Wei Deng
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Power supply to the M.2 Bluetooth device attached to the host using M.2
connector is controlled using the 'uart' pwrseq device. So add support for
getting the pwrseq device if the OF graph link is present. Once obtained,
the existing pwrseq APIs can be used to control the power supplies of the
M.2 card.
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Tested-by: Wei Deng <wei.deng@oss.qualcomm.com>
---
drivers/bluetooth/hci_qca.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 2444471956197bae62a1c4c3a776c5591780ec02..135c79e696aefe2b37ee7a7a668715360a1e2d75 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -26,6 +26,7 @@
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_graph.h>
#include <linux/acpi.h>
#include <linux/platform_device.h>
#include <linux/pwrseq/consumer.h>
@@ -2445,6 +2446,18 @@ static int qca_serdev_probe(struct serdev_device *serdev)
case QCA_WCN6750:
case QCA_WCN6855:
case QCA_WCN7850:
+ /*
+ * OF graph link is only present for BT devices attached through
+ * the M.2 Key E connector.
+ */
+ if (of_graph_is_present(dev_of_node(&serdev->ctrl->dev))) {
+ qcadev->bt_power->pwrseq = devm_pwrseq_get(&serdev->ctrl->dev,
+ "uart");
+ if (IS_ERR(qcadev->bt_power->pwrseq))
+ return PTR_ERR(qcadev->bt_power->pwrseq);
+ break;
+ }
+
if (!device_property_present(&serdev->dev, "enable-gpios")) {
/*
* Backward compatibility with old DT sources. If the
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v4 01/11] Bluetooth: hci_qca: Add M.2 Bluetooth device support using pwrseq
@ 2026-07-16 16:18 Loic Poulain
2026-07-16 16:55 ` arm64: dts: monaco-arduino-monza: Add support for LGA WiFi/BT module bluez.test.bot
0 siblings, 1 reply; 24+ messages in thread
From: Loic Poulain @ 2026-07-16 16:18 UTC (permalink / raw)
To: Manivannan Sadhasivam, Bartosz Golaszewski, Marcel Holtmann,
Luiz Augusto von Dentz, Bjorn Andersson, Konrad Dybcio,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pci, linux-pm, linux-kernel, linux-arm-msm, linux-bluetooth,
devicetree, Manivannan Sadhasivam, Loic Poulain,
Bartosz Golaszewski, Dmitry Baryshkov, Wei Deng
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Power supply to the M.2 Bluetooth device attached to the host using M.2
connector is controlled using the 'uart' pwrseq device. So add support for
getting the pwrseq device if the OF graph link is present. Once obtained,
the existing pwrseq APIs can be used to control the power supplies of the
M.2 card.
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Tested-by: Wei Deng <wei.deng@oss.qualcomm.com>
---
drivers/bluetooth/hci_qca.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 2444471956197bae62a1c4c3a776c5591780ec02..135c79e696aefe2b37ee7a7a668715360a1e2d75 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -26,6 +26,7 @@
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_graph.h>
#include <linux/acpi.h>
#include <linux/platform_device.h>
#include <linux/pwrseq/consumer.h>
@@ -2445,6 +2446,18 @@ static int qca_serdev_probe(struct serdev_device *serdev)
case QCA_WCN6750:
case QCA_WCN6855:
case QCA_WCN7850:
+ /*
+ * OF graph link is only present for BT devices attached through
+ * the M.2 Key E connector.
+ */
+ if (of_graph_is_present(dev_of_node(&serdev->ctrl->dev))) {
+ qcadev->bt_power->pwrseq = devm_pwrseq_get(&serdev->ctrl->dev,
+ "uart");
+ if (IS_ERR(qcadev->bt_power->pwrseq))
+ return PTR_ERR(qcadev->bt_power->pwrseq);
+ break;
+ }
+
if (!device_property_present(&serdev->dev, "enable-gpios")) {
/*
* Backward compatibility with old DT sources. If the
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v3 01/11] Bluetooth: hci_qca: Add M.2 Bluetooth device support using pwrseq
@ 2026-07-10 9:57 Loic Poulain
2026-07-10 10:44 ` arm64: dts: monaco-arduino-monza: Add support for LGA WiFi/BT module bluez.test.bot
0 siblings, 1 reply; 24+ messages in thread
From: Loic Poulain @ 2026-07-10 9:57 UTC (permalink / raw)
To: Manivannan Sadhasivam, Bartosz Golaszewski, Marcel Holtmann,
Luiz Augusto von Dentz, Bjorn Andersson, Konrad Dybcio,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pci, linux-pm, linux-kernel, linux-arm-msm, linux-bluetooth,
devicetree, Manivannan Sadhasivam, Loic Poulain,
Bartosz Golaszewski, Dmitry Baryshkov, Wei Deng
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Power supply to the M.2 Bluetooth device attached to the host using M.2
connector is controlled using the 'uart' pwrseq device. So add support for
getting the pwrseq device if the OF graph link is present. Once obtained,
the existing pwrseq APIs can be used to control the power supplies of the
M.2 card.
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Tested-by: Wei Deng <wei.deng@oss.qualcomm.com>
---
drivers/bluetooth/hci_qca.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 2444471956197bae62a1c4c3a776c5591780ec02..135c79e696aefe2b37ee7a7a668715360a1e2d75 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -26,6 +26,7 @@
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_graph.h>
#include <linux/acpi.h>
#include <linux/platform_device.h>
#include <linux/pwrseq/consumer.h>
@@ -2445,6 +2446,18 @@ static int qca_serdev_probe(struct serdev_device *serdev)
case QCA_WCN6750:
case QCA_WCN6855:
case QCA_WCN7850:
+ /*
+ * OF graph link is only present for BT devices attached through
+ * the M.2 Key E connector.
+ */
+ if (of_graph_is_present(dev_of_node(&serdev->ctrl->dev))) {
+ qcadev->bt_power->pwrseq = devm_pwrseq_get(&serdev->ctrl->dev,
+ "uart");
+ if (IS_ERR(qcadev->bt_power->pwrseq))
+ return PTR_ERR(qcadev->bt_power->pwrseq);
+ break;
+ }
+
if (!device_property_present(&serdev->dev, "enable-gpios")) {
/*
* Backward compatibility with old DT sources. If the
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v2 1/4] dt-bindings: connector: pcie-m2-e: Add vendor LGA connector compatible
@ 2026-07-02 10:46 Loic Poulain
2026-07-02 12:29 ` arm64: dts: monaco-arduino-monza: Add support for LGA WiFi/BT module bluez.test.bot
0 siblings, 1 reply; 24+ messages in thread
From: Loic Poulain @ 2026-07-02 10:46 UTC (permalink / raw)
To: Manivannan Sadhasivam, Bartosz Golaszewski, Marcel Holtmann,
Luiz Augusto von Dentz, Bjorn Andersson, Konrad Dybcio,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pci, linux-pm, linux-kernel, linux-arm-msm, linux-bluetooth,
devicetree, Manivannan Sadhasivam, Loic Poulain
Some modules (e.g. the Qualcomm QCA2066/QCNFA765) expose the same M.2
Key E interface signals but are physically soldered as an LGA package
rather than plugged into a real M.2 Key E connector socket. Such designs
are not actual M.2 Key E connectors, so describe them with a dedicated
vendor-specific compatible while keeping "pcie-m2-e-connector" as a
fallback for the shared signal semantics.
Add "qcom,pcie-m2-1418-lga-connector" for the M.2 LGA 1418 module.
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
---
.../devicetree/bindings/connector/pcie-m2-e-connector.yaml | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml b/Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml
index f7859aa9b63469cb43919c0b5719c18694c5364d..0282c6ee9272446064a99ec6314a5ceb1721e0c4 100644
--- a/Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml
+++ b/Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml
@@ -17,7 +17,12 @@ description:
properties:
compatible:
- const: pcie-m2-e-connector
+ oneOf:
+ - const: pcie-m2-e-connector
+ - items:
+ - enum:
+ - qcom,pcie-m2-1418-lga-connector
+ - const: pcie-m2-e-connector
vpcie3v3-supply:
description: A phandle to the regulator for 3.3v supply.
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
end of thread, other threads:[~2026-10-07 22:58 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-05 12:21 [PATCH v7 0/8] arm64: dts: monaco-arduino-monza: Add support for LGA WiFi/BT module Loic Poulain
2026-10-05 12:21 ` [PATCH v7 1/8] Bluetooth: hci_qca: Add M.2 Bluetooth device support using pwrseq Loic Poulain
2026-10-05 12:29 ` sashiko-bot
2026-10-05 13:01 ` arm64: dts: monaco-arduino-monza: Add support for LGA WiFi/BT module bluez.test.bot
2026-10-05 12:21 ` [PATCH v7 2/8] Bluetooth: hci_qca: Rename 'power_ctrl_enabled' to 'bt_en_available' Loic Poulain
2026-10-05 12:28 ` sashiko-bot
2026-10-05 12:21 ` [PATCH v7 3/8] Bluetooth: hci_qca: Set 'bt_en_available' based on pwrseq power controllability Loic Poulain
2026-10-05 12:33 ` sashiko-bot
2026-10-05 12:21 ` [PATCH v7 4/8] Bluetooth: hci_qca: Embed bt_power in struct qca_serdev Loic Poulain
2026-10-05 12:29 ` sashiko-bot
2026-10-05 12:21 ` [PATCH v7 5/8] Bluetooth: hci_qca: Support QCA2066 on M.2 connector via pwrseq Loic Poulain
2026-10-05 12:33 ` sashiko-bot
2026-10-07 22:57 ` Val Packett
2026-10-05 12:21 ` [PATCH v7 6/8] Bluetooth: hci_qca: Flatten struct qca_power into struct qca_serdev Loic Poulain
2026-10-05 12:29 ` sashiko-bot
2026-10-05 12:21 ` [PATCH v7 7/8] dt-bindings: connector: pcie-m2-e: Add vendor LGA connector compatible Loic Poulain
2026-10-05 12:23 ` sashiko-bot
2026-10-05 12:21 ` [PATCH v7 8/8] arm64: dts: qcom: monaco-arduino-monza: Add QCA2066 M.2 WiFi/BT support Loic Poulain
2026-10-05 12:37 ` sashiko-bot
-- strict thread matches above, loose matches on Subject: below --
2026-09-04 15:42 [PATCH v6 01/11] Bluetooth: hci_qca: Add M.2 Bluetooth device support using pwrseq Loic Poulain
2026-09-04 17:21 ` arm64: dts: monaco-arduino-monza: Add support for LGA WiFi/BT module bluez.test.bot
2026-07-20 8:04 [PATCH v5 01/11] Bluetooth: hci_qca: Add M.2 Bluetooth device support using pwrseq Loic Poulain
2026-07-20 9:51 ` arm64: dts: monaco-arduino-monza: Add support for LGA WiFi/BT module bluez.test.bot
2026-07-16 16:18 [PATCH v4 01/11] Bluetooth: hci_qca: Add M.2 Bluetooth device support using pwrseq Loic Poulain
2026-07-16 16:55 ` arm64: dts: monaco-arduino-monza: Add support for LGA WiFi/BT module bluez.test.bot
2026-07-10 9:57 [PATCH v3 01/11] Bluetooth: hci_qca: Add M.2 Bluetooth device support using pwrseq Loic Poulain
2026-07-10 10:44 ` arm64: dts: monaco-arduino-monza: Add support for LGA WiFi/BT module bluez.test.bot
2026-07-02 10:46 [PATCH v2 1/4] dt-bindings: connector: pcie-m2-e: Add vendor LGA connector compatible Loic Poulain
2026-07-02 12:29 ` arm64: dts: monaco-arduino-monza: Add support for LGA WiFi/BT module bluez.test.bot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.