* [PATCH 1/3] arm64: dts: qcom: hamoa-iot-evk: Describe the PCIe M.2 Key E connector
2026-07-09 7:29 [PATCH 0/3] power: sequencing: pcie-m2: Enable USB/UART BT coexistence on Hamoa EVK Wei Deng
@ 2026-07-09 7:29 ` Wei Deng
2026-07-09 7:42 ` sashiko-bot
` (2 more replies)
2026-07-09 7:29 ` [PATCH 2/3] power: sequencing: pcie-m2: Match WCN6855 and WCN7851 UART BT variants by subdevice ID Wei Deng
` (2 subsequent siblings)
3 siblings, 3 replies; 13+ messages in thread
From: Wei Deng @ 2026-07-09 7:29 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Manivannan Sadhasivam, Bartosz Golaszewski
Cc: linux-arm-msm, devicetree, linux-kernel, linux-pci, linux-pm,
Wei Deng, mengshi.wu
The hamoa IoT EVK has the PCIe M.2 Mechanical Key E connector to
connect wireless connectivity cards over PCIe and UART interfaces.
Hence, describe the connector node, link it with the PCIe 4 Root Port
node and replace the static BT serdev under UART14 and the
chip-specific wifi@0 child node with graph port/endpoints, allowing
the pwrseq-pcie-m2 driver to power the card and dynamically create
the BT serdev device.
The M.2 Key E connector is powered by vreg_wcn_3p3. WLAN enable is
controlled via W_DISABLE1# (GPIO117) and BT enable via W_DISABLE2#
(GPIO116), both described as active-low GPIOs on the connector node.
Remove the chip-specific wcn7850-pmu node as the M.2 connector
approach replaces the WCN7850-specific power sequencing with a
chip-agnostic one managed by the pwrseq-pcie-m2 driver.
Also add 'compatible = "pciclass,0604"' to pcie4_port0 in hamoa.dtsi
to allow the PCI subsystem to associate the DT node with the
PCI-to-PCI bridge device.
Signed-off-by: Wei Deng <wei.deng@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts | 129 ++++++++++-------------------
arch/arm64/boot/dts/qcom/hamoa.dtsi | 1 +
2 files changed, 47 insertions(+), 83 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts
index 9fa86bb6438e..41c2004f0ef6 100644
--- a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts
+++ b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts
@@ -68,6 +68,44 @@ chosen {
stdout-path = "serial0:115200n8";
};
+ connector {
+ compatible = "pcie-m2-e-connector";
+ vpcie3v3-supply = <&vreg_wcn_3p3>;
+
+ w-disable1-gpios = <&tlmm 117 GPIO_ACTIVE_LOW>;
+ w-disable2-gpios = <&tlmm 116 GPIO_ACTIVE_LOW>;
+
+ pinctrl-0 = <&wcn_wlan_en>, <&wcn_bt_en>;
+ pinctrl-names = "default";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ m2_e_pcie_ep: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&pcie4port0_ep>;
+ };
+ };
+
+ port@3 {
+ reg = <3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ m2_e_uart_ep: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&uart14_ep>;
+ };
+ };
+ };
+ };
+
connector3 {
compatible = "usb-a-connector";
label = "USB-3-Type-A";
@@ -676,65 +714,6 @@ usb_1_ss0_sbu_mux: endpoint {
};
};
};
-
- wcn7850-pmu {
- compatible = "qcom,wcn7850-pmu";
-
- vdd-supply = <&vreg_wcn_0p95>;
- vddio-supply = <&vreg_l15b_1p8>;
- vddaon-supply = <&vreg_wcn_0p95>;
- vdddig-supply = <&vreg_wcn_0p95>;
- vddrfa1p2-supply = <&vreg_wcn_1p9>;
- vddrfa1p8-supply = <&vreg_wcn_1p9>;
-
- bt-enable-gpios = <&tlmm 116 GPIO_ACTIVE_HIGH>;
- wlan-enable-gpios = <&tlmm 117 GPIO_ACTIVE_HIGH>;
-
- pinctrl-0 = <&wcn_bt_en>, <&wcn_wlan_en>;
- pinctrl-names = "default";
-
- regulators {
- vreg_pmu_rfa_cmn: ldo0 {
- regulator-name = "vreg_pmu_rfa_cmn";
- };
-
- vreg_pmu_aon_0p59: ldo1 {
- regulator-name = "vreg_pmu_aon_0p59";
- };
-
- vreg_pmu_wlcx_0p8: ldo2 {
- regulator-name = "vreg_pmu_wlcx_0p8";
- };
-
- vreg_pmu_wlmx_0p85: ldo3 {
- regulator-name = "vreg_pmu_wlmx_0p85";
- };
-
- vreg_pmu_btcmx_0p85: ldo4 {
- regulator-name = "vreg_pmu_btcmx_0p85";
- };
-
- vreg_pmu_rfa_0p8: ldo5 {
- regulator-name = "vreg_pmu_rfa_0p8";
- };
-
- vreg_pmu_rfa_1p2: ldo6 {
- regulator-name = "vreg_pmu_rfa_1p2";
- };
-
- vreg_pmu_rfa_1p8: ldo7 {
- regulator-name = "vreg_pmu_rfa_1p8";
- };
-
- vreg_pmu_pcie_0p9: ldo8 {
- regulator-name = "vreg_pmu_pcie_0p9";
- };
-
- vreg_pmu_pcie_1p8: ldo9 {
- regulator-name = "vreg_pmu_pcie_1p8";
- };
- };
- };
};
&i2c1 {
@@ -1025,19 +1004,10 @@ &pcie4_port0 {
reset-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>;
- wifi@0 {
- compatible = "pci17cb,1107";
- reg = <0x10000 0x0 0x0 0x0 0x0>;
-
- vddaon-supply = <&vreg_pmu_aon_0p59>;
- vddwlcx-supply = <&vreg_pmu_wlcx_0p8>;
- vddwlmx-supply = <&vreg_pmu_wlmx_0p85>;
- vddrfacmn-supply = <&vreg_pmu_rfa_cmn>;
- vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>;
- vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
- vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>;
- vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>;
- vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>;
+ port {
+ pcie4port0_ep: endpoint {
+ remote-endpoint = <&m2_e_pcie_ep>;
+ };
};
};
@@ -1531,17 +1501,10 @@ wcn_usb_sw_n: wcn-usb-sw-n-state {
&uart14 {
status = "okay";
- bluetooth {
- compatible = "qcom,wcn7850-bt";
- max-speed = <3200000>;
-
- vddaon-supply = <&vreg_pmu_aon_0p59>;
- vddwlcx-supply = <&vreg_pmu_wlcx_0p8>;
- vddwlmx-supply = <&vreg_pmu_wlmx_0p85>;
- vddrfacmn-supply = <&vreg_pmu_rfa_cmn>;
- vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>;
- vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
- vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>;
+ port {
+ uart14_ep: endpoint {
+ remote-endpoint = <&m2_e_uart_ep>;
+ };
};
};
diff --git a/arch/arm64/boot/dts/qcom/hamoa.dtsi b/arch/arm64/boot/dts/qcom/hamoa.dtsi
index 60f485a4892e..566a6b4c6208 100644
--- a/arch/arm64/boot/dts/qcom/hamoa.dtsi
+++ b/arch/arm64/boot/dts/qcom/hamoa.dtsi
@@ -3776,6 +3776,7 @@ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
pcie4_port0: pcie@0 {
device_type = "pci";
+ compatible = "pciclass,0604";
reg = <0x0 0x0 0x0 0x0 0x0>;
bus-range = <0x01 0xff>;
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH 1/3] arm64: dts: qcom: hamoa-iot-evk: Describe the PCIe M.2 Key E connector
2026-07-09 7:29 ` [PATCH 1/3] arm64: dts: qcom: hamoa-iot-evk: Describe the PCIe M.2 Key E connector Wei Deng
@ 2026-07-09 7:42 ` sashiko-bot
2026-07-09 7:44 ` Dmitry Baryshkov
2026-07-10 13:50 ` Konrad Dybcio
2 siblings, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-07-09 7:42 UTC (permalink / raw)
To: Wei Deng; +Cc: conor+dt, devicetree, linux-pci, robh
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] Unused dummy fixed regulators `vreg_wcn_0p95` and `vreg_wcn_1p9` are left orphaned in the device tree.
--
--- Patch [1]: [PATCH 1/3] arm64: dts: qcom: hamoa-iot-evk: Describe the PCIe M.2 Key E connector ---
commit 3a5c700f021e92c47e3fa3997595501dd58c45d6
Author: Wei Deng <wei.deng@oss.qualcomm.com>
arm64: dts: qcom: hamoa-iot-evk: Describe the PCIe M.2 Key E connector
This commit describes the PCIe M.2 Mechanical Key E connector in the hamoa IoT
EVK device tree, linking it to the PCIe 4 Root Port. It replaces the specific
wcn7850-pmu and static BT nodes with chip-agnostic pwrseq-pcie-m2 driver
endpoints.
> diff --git a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts
> index 9fa86bb6438ec..41c2004f0ef67 100644
> --- a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts
> +++ b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts
[ ... ]
> @@ -676,65 +714,6 @@ usb_1_ss0_sbu_mux: endpoint {
> };
> };
> };
> -
> - wcn7850-pmu {
> - compatible = "qcom,wcn7850-pmu";
> -
> - vdd-supply = <&vreg_wcn_0p95>;
> - vddio-supply = <&vreg_l15b_1p8>;
> - vddaon-supply = <&vreg_wcn_0p95>;
> - vdddig-supply = <&vreg_wcn_0p95>;
> - vddrfa1p2-supply = <&vreg_wcn_1p9>;
> - vddrfa1p8-supply = <&vreg_wcn_1p9>;
[Severity: Low]
Since the wcn7850-pmu node is removed here and the wifi@0 node is removed
below, their consumers are gone.
Should the corresponding fixed regulator definitions for vreg_wcn_0p95 and
vreg_wcn_1p9 also be removed from the device tree?
Leaving them behind might cause the regulator core to needlessly instantiate
these dummy regulators.
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260709-fix-hamoa-m2-w-disable2-v1-0-5e725091266a@oss.qualcomm.com?part=1
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH 1/3] arm64: dts: qcom: hamoa-iot-evk: Describe the PCIe M.2 Key E connector
2026-07-09 7:29 ` [PATCH 1/3] arm64: dts: qcom: hamoa-iot-evk: Describe the PCIe M.2 Key E connector Wei Deng
2026-07-09 7:42 ` sashiko-bot
@ 2026-07-09 7:44 ` Dmitry Baryshkov
2026-07-09 8:12 ` Wei Deng
2026-07-10 13:50 ` Konrad Dybcio
2 siblings, 1 reply; 13+ messages in thread
From: Dmitry Baryshkov @ 2026-07-09 7:44 UTC (permalink / raw)
To: Wei Deng
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Manivannan Sadhasivam, Bartosz Golaszewski,
linux-arm-msm, devicetree, linux-kernel, linux-pci, linux-pm,
mengshi.wu
On Thu, Jul 09, 2026 at 12:59:40PM +0530, Wei Deng wrote:
> The hamoa IoT EVK has the PCIe M.2 Mechanical Key E connector to
> connect wireless connectivity cards over PCIe and UART interfaces.
> Hence, describe the connector node, link it with the PCIe 4 Root Port
> node and replace the static BT serdev under UART14 and the
> chip-specific wifi@0 child node with graph port/endpoints, allowing
> the pwrseq-pcie-m2 driver to power the card and dynamically create
> the BT serdev device.
>
> The M.2 Key E connector is powered by vreg_wcn_3p3. WLAN enable is
> controlled via W_DISABLE1# (GPIO117) and BT enable via W_DISABLE2#
> (GPIO116), both described as active-low GPIOs on the connector node.
>
> Remove the chip-specific wcn7850-pmu node as the M.2 connector
> approach replaces the WCN7850-specific power sequencing with a
> chip-agnostic one managed by the pwrseq-pcie-m2 driver.
>
> Also add 'compatible = "pciclass,0604"' to pcie4_port0 in hamoa.dtsi
> to allow the PCI subsystem to associate the DT node with the
> PCI-to-PCI bridge device.
Separate, unrelated change?
>
> Signed-off-by: Wei Deng <wei.deng@oss.qualcomm.com>
> ---
> arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts | 129 ++++++++++-------------------
> arch/arm64/boot/dts/qcom/hamoa.dtsi | 1 +
> 2 files changed, 47 insertions(+), 83 deletions(-)
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/3] arm64: dts: qcom: hamoa-iot-evk: Describe the PCIe M.2 Key E connector
2026-07-09 7:44 ` Dmitry Baryshkov
@ 2026-07-09 8:12 ` Wei Deng
0 siblings, 0 replies; 13+ messages in thread
From: Wei Deng @ 2026-07-09 8:12 UTC (permalink / raw)
To: dmitry.baryshkov
Cc: andersson, konradybcio, robh, krzk+dt, conor+dt, mani, brgl,
linux-arm-msm, devicetree, linux-kernel, linux-pci, linux-pm
On Thu, 9 Jul 2026, Dmitry Baryshkov wrote:
> Separate, unrelated change?
Agreed, will split it into a separate commit in v2.
--
Best Regards,
Wei Deng
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/3] arm64: dts: qcom: hamoa-iot-evk: Describe the PCIe M.2 Key E connector
2026-07-09 7:29 ` [PATCH 1/3] arm64: dts: qcom: hamoa-iot-evk: Describe the PCIe M.2 Key E connector Wei Deng
2026-07-09 7:42 ` sashiko-bot
2026-07-09 7:44 ` Dmitry Baryshkov
@ 2026-07-10 13:50 ` Konrad Dybcio
2 siblings, 0 replies; 13+ messages in thread
From: Konrad Dybcio @ 2026-07-10 13:50 UTC (permalink / raw)
To: Wei Deng, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Manivannan Sadhasivam,
Bartosz Golaszewski
Cc: linux-arm-msm, devicetree, linux-kernel, linux-pci, linux-pm,
mengshi.wu
On 7/9/26 9:29 AM, Wei Deng wrote:
> The hamoa IoT EVK has the PCIe M.2 Mechanical Key E connector to
> connect wireless connectivity cards over PCIe and UART interfaces.
> Hence, describe the connector node, link it with the PCIe 4 Root Port
> node and replace the static BT serdev under UART14 and the
> chip-specific wifi@0 child node with graph port/endpoints, allowing
> the pwrseq-pcie-m2 driver to power the card and dynamically create
> the BT serdev device.
>
> The M.2 Key E connector is powered by vreg_wcn_3p3. WLAN enable is
> controlled via W_DISABLE1# (GPIO117) and BT enable via W_DISABLE2#
> (GPIO116), both described as active-low GPIOs on the connector node.
>
> Remove the chip-specific wcn7850-pmu node as the M.2 connector
> approach replaces the WCN7850-specific power sequencing with a
> chip-agnostic one managed by the pwrseq-pcie-m2 driver.
>
> Also add 'compatible = "pciclass,0604"' to pcie4_port0 in hamoa.dtsi
> to allow the PCI subsystem to associate the DT node with the
> PCI-to-PCI bridge device.
>
> Signed-off-by: Wei Deng <wei.deng@oss.qualcomm.com>
> ---
[...]
> @@ -1025,19 +1004,10 @@ &pcie4_port0 {
> reset-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>;
> wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>;
>
> - wifi@0 {
> - compatible = "pci17cb,1107";
> - reg = <0x10000 0x0 0x0 0x0 0x0>;
> -
> - vddaon-supply = <&vreg_pmu_aon_0p59>;
> - vddwlcx-supply = <&vreg_pmu_wlcx_0p8>;
> - vddwlmx-supply = <&vreg_pmu_wlmx_0p85>;
> - vddrfacmn-supply = <&vreg_pmu_rfa_cmn>;
> - vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>;
> - vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
> - vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>;
> - vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>;
> - vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>;
> + port {
> + pcie4port0_ep: endpoint {
"pcie4_port0_ep", please
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Konrad
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 2/3] power: sequencing: pcie-m2: Match WCN6855 and WCN7851 UART BT variants by subdevice ID
2026-07-09 7:29 [PATCH 0/3] power: sequencing: pcie-m2: Enable USB/UART BT coexistence on Hamoa EVK Wei Deng
2026-07-09 7:29 ` [PATCH 1/3] arm64: dts: qcom: hamoa-iot-evk: Describe the PCIe M.2 Key E connector Wei Deng
@ 2026-07-09 7:29 ` Wei Deng
2026-07-09 7:39 ` sashiko-bot
2026-07-09 7:29 ` [PATCH 3/3] power: sequencing: pcie-m2: Deassert W_DISABLE2# when no UART serdev is created Wei Deng
2026-07-09 7:46 ` [PATCH 0/3] power: sequencing: pcie-m2: Enable USB/UART BT coexistence on Hamoa EVK Dmitry Baryshkov
3 siblings, 1 reply; 13+ messages in thread
From: Wei Deng @ 2026-07-09 7:29 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Manivannan Sadhasivam, Bartosz Golaszewski
Cc: linux-arm-msm, devicetree, linux-kernel, linux-pci, linux-pm,
Wei Deng, mengshi.wu
The WCN6855 and WCN7851 combo chips are available in M.2 card variants
that differ by their BT interface: some expose BT over UART while others
expose BT over USB. Both variants use the same PCIe device ID for the
WiFi interface, distinguished only by their sub-system device ID.
The bare PCI_DEVICE() entries match all sub-system IDs, so both UART and
USB variants hit the same table entry and trigger UART serdev creation.
For USB variants this is wrong — there is no UART BT interface on such
a card, and the serdev probe will fail.
Narrow the matches to UART variants only by using PCI_DEVICE_SUB with
their respective sub-system IDs. USB variants no longer match the table
and will be handled separately to deassert W_DISABLE2# for USB BT
enumeration.
Signed-off-by: Wei Deng <wei.deng@oss.qualcomm.com>
---
drivers/power/sequencing/pwrseq-pcie-m2.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/power/sequencing/pwrseq-pcie-m2.c b/drivers/power/sequencing/pwrseq-pcie-m2.c
index 83fe6a1396bc..cf51122d54fd 100644
--- a/drivers/power/sequencing/pwrseq-pcie-m2.c
+++ b/drivers/power/sequencing/pwrseq-pcie-m2.c
@@ -191,9 +191,11 @@ static const struct pci_device_id pwrseq_m2_pci_ids[] = {
.driver_data = (kernel_ulong_t)"nxp,88w8987-bt" },
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x1103, PCI_VENDOR_ID_QCOM, 0x0108),
.driver_data = (kernel_ulong_t)"qcom,qca2066-bt" },
- { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x1103),
+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x1103, PCI_VENDOR_ID_FOXCONN, 0xe105),
.driver_data = (kernel_ulong_t)"qcom,wcn6855-bt" },
- { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x1107),
+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x1103, PCI_VENDOR_ID_QCOM, 0x337e),
+ .driver_data = (kernel_ulong_t)"qcom,wcn6855-bt" },
+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x1107, PCI_VENDOR_ID_QCOM, 0x337c),
.driver_data = (kernel_ulong_t)"qcom,wcn7850-bt" },
{ PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x1112),
.driver_data = (kernel_ulong_t)"qcom,qcc2072-bt" },
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 3/3] power: sequencing: pcie-m2: Deassert W_DISABLE2# when no UART serdev is created
2026-07-09 7:29 [PATCH 0/3] power: sequencing: pcie-m2: Enable USB/UART BT coexistence on Hamoa EVK Wei Deng
2026-07-09 7:29 ` [PATCH 1/3] arm64: dts: qcom: hamoa-iot-evk: Describe the PCIe M.2 Key E connector Wei Deng
2026-07-09 7:29 ` [PATCH 2/3] power: sequencing: pcie-m2: Match WCN6855 and WCN7851 UART BT variants by subdevice ID Wei Deng
@ 2026-07-09 7:29 ` Wei Deng
2026-07-09 7:44 ` sashiko-bot
2026-07-09 7:56 ` Dmitry Baryshkov
2026-07-09 7:46 ` [PATCH 0/3] power: sequencing: pcie-m2: Enable USB/UART BT coexistence on Hamoa EVK Dmitry Baryshkov
3 siblings, 2 replies; 13+ messages in thread
From: Wei Deng @ 2026-07-09 7:29 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Manivannan Sadhasivam, Bartosz Golaszewski
Cc: linux-arm-msm, devicetree, linux-kernel, linux-pci, linux-pm,
Wei Deng, mengshi.wu
The pwrseq_m2_pci_ids[] table lists PCIe BT devices that use UART as the
BT transport and need a UART serdev created by the driver. When a PCIe
device under the M.2 connector does not match any entry in this table,
no UART serdev is created.
However, the BT subsystem of such a device may still require W_DISABLE2#
to be deasserted to power up. Rather than adding every possible non-UART
BT device ID to the table, add an else branch that deasserts W_DISABLE2#
whenever a PCIe device is detected under the connector but does not match
a UART BT entry. This allows any BT interface on the card (USB or other)
to enumerate without requiring explicit knowledge of its device ID.
The primary use case is USB BT variants of combo chips that share the
same PCIe device ID as their UART counterpart (e.g. WCN7851 NCM865 USB,
sub 0x3378, vs NCM865A UART, sub 0x337c): no UART serdev is needed, but
W_DISABLE2# must be deasserted so the USB BT device can enumerate.
Reassert W_DISABLE2# symmetrically when the PCIe device is removed.
Validated on Hamoa EVK (IQ-X7181-EVK) with WCN7851 NCM865 USB card
(sub 0x3378): without this change GPIO116 (W_DISABLE2#) stays low and
no BT interface appears; with this change GPIO116 is driven high and the
USB BT device enumerates and comes up via btusb.
Signed-off-by: Wei Deng <wei.deng@oss.qualcomm.com>
---
drivers/power/sequencing/pwrseq-pcie-m2.c | 33 +++++++++++++++++++++----------
1 file changed, 23 insertions(+), 10 deletions(-)
diff --git a/drivers/power/sequencing/pwrseq-pcie-m2.c b/drivers/power/sequencing/pwrseq-pcie-m2.c
index cf51122d54fd..06eb5eb0676b 100644
--- a/drivers/power/sequencing/pwrseq-pcie-m2.c
+++ b/drivers/power/sequencing/pwrseq-pcie-m2.c
@@ -401,11 +401,23 @@ static int pwrseq_pcie_m2_notify(struct notifier_block *nb, unsigned long action
ret = pwrseq_pcie_m2_create_serdev_one(ctx, pdev);
if (ret)
return notifier_from_errno(ret);
+ } else if (ctx->w_disable2_gpio) {
+ /*
+ * PCIe device not in the UART BT table. This covers
+ * USB BT variants of the same combo chip (same PCIe
+ * device ID, different sub-system ID, BT exposed over
+ * USB instead of UART). No UART serdev is needed, but
+ * W_DISABLE2# must be deasserted to enable the BT
+ * subsystem so the USB BT interface can enumerate.
+ */
+ gpiod_set_value_cansleep(ctx->w_disable2_gpio, 0);
}
break;
case BUS_NOTIFY_REMOVED_DEVICE:
if (pci_match_id(pwrseq_m2_pci_ids, pdev))
pwrseq_pcie_m2_remove_serdev(ctx, pdev);
+ else if (ctx->w_disable2_gpio)
+ gpiod_set_value_cansleep(ctx->w_disable2_gpio, 1);
break;
}
@@ -469,16 +481,17 @@ static int pwrseq_pcie_m2_create_serdev(struct pwrseq_pcie_m2_ctx *ctx)
if (!pdev->dev.parent || pci_parent != pdev->dev.parent->of_node)
continue;
- if (!pci_match_id(pwrseq_m2_pci_ids, pdev))
- continue;
-
- ret = pwrseq_pcie_m2_create_serdev_one(ctx, pdev);
- if (ret) {
- dev_err_probe(ctx->dev, ret,
- "Failed to create serdev for PCI device (%s)\n",
- pci_name(pdev));
- pci_dev_put(pdev);
- goto err_remove_serdev;
+ if (pci_match_id(pwrseq_m2_pci_ids, pdev)) {
+ ret = pwrseq_pcie_m2_create_serdev_one(ctx, pdev);
+ if (ret) {
+ dev_err_probe(ctx->dev, ret,
+ "Failed to create serdev for PCI device (%s)\n",
+ pci_name(pdev));
+ pci_dev_put(pdev);
+ goto err_remove_serdev;
+ }
+ } else if (ctx->w_disable2_gpio) {
+ gpiod_set_value_cansleep(ctx->w_disable2_gpio, 0);
}
}
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH 3/3] power: sequencing: pcie-m2: Deassert W_DISABLE2# when no UART serdev is created
2026-07-09 7:29 ` [PATCH 3/3] power: sequencing: pcie-m2: Deassert W_DISABLE2# when no UART serdev is created Wei Deng
@ 2026-07-09 7:44 ` sashiko-bot
2026-07-09 7:56 ` Dmitry Baryshkov
1 sibling, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-07-09 7:44 UTC (permalink / raw)
To: Wei Deng; +Cc: devicetree, robh, linux-pci, conor+dt
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
New issues:
- [High] Unconditional toggling of shared W_DISABLE2# GPIO causes premature assertion for multi-function PCI devices.
- [High] Missing cleanup of manually managed W_DISABLE2# GPIO on module removal and probe error paths.
Pre-existing issues:
- [High] Missing notification of PCI devices hotplugged between existing device iteration and notifier registration.
--
--- Patch [3]: [PATCH 3/3] power: sequencing: pcie-m2: Deassert W_DISABLE2# when no UART serdev is created ---
commit b301a8670a82271ce018fc9f630c8d02f37d6f72
Author: Wei Deng <wei.deng@oss.qualcomm.com>
Subject: power: sequencing: pcie-m2: Deassert W_DISABLE2# when no UART serdev is created
This commit modifies the PCIe M.2 power sequencing driver to handle
non-UART Bluetooth devices, such as USB variants. It deasserts the
W_DISABLE2# GPIO for devices not in the UART list to allow them to
enumerate, and reasserts it symmetrically upon device removal.
> diff --git a/drivers/power/sequencing/pwrseq-pcie-m2.c b/drivers/power/sequencing/pwrseq-pcie-m2.c
> index cf51122d54fdf..06eb5eb0676bd 100644
> --- a/drivers/power/sequencing/pwrseq-pcie-m2.c
> +++ b/drivers/power/sequencing/pwrseq-pcie-m2.c
[ ... ]
> @@ -401,11 +401,23 @@ static int pwrseq_pcie_m2_notify(struct notifier_block *nb, unsigned long action
> ret = pwrseq_pcie_m2_create_serdev_one(ctx, pdev);
> if (ret)
> return notifier_from_errno(ret);
> + } else if (ctx->w_disable2_gpio) {
> + /*
> + * PCIe device not in the UART BT table. This covers
> + * USB BT variants of the same combo chip (same PCIe
> + * device ID, different sub-system ID, BT exposed over
> + * USB instead of UART). No UART serdev is needed, but
> + * W_DISABLE2# must be deasserted to enable the BT
> + * subsystem so the USB BT interface can enumerate.
> + */
> + gpiod_set_value_cansleep(ctx->w_disable2_gpio, 0);
> }
> break;
> case BUS_NOTIFY_REMOVED_DEVICE:
> if (pci_match_id(pwrseq_m2_pci_ids, pdev))
> pwrseq_pcie_m2_remove_serdev(ctx, pdev);
> + else if (ctx->w_disable2_gpio)
> + gpiod_set_value_cansleep(ctx->w_disable2_gpio, 1);
[Severity: High]
If a multi-function M.2 combo card exposes multiple PCI functions (e.g., a
dual-function endpoint where both functions share the same root port parent),
does this code prematurely power off the Bluetooth subsystem when one
function is removed?
Adding a multi-function non-UART PCI device triggers BUS_NOTIFY_ADD_DEVICE
multiple times (once per function), which will redundantly set the GPIO
to 0.
When one of these functions is later unbound or removed,
BUS_NOTIFY_REMOVED_DEVICE fires and unconditionally sets the GPIO to 1.
Will this break the remaining active functions and the USB BT subsystem
since there is no state tracking or refcounting for the GPIO toggling?
[ ... ]
> @@ -469,16 +481,17 @@ static int pwrseq_pcie_m2_create_serdev(struct pwrseq_pcie_m2_ctx *ctx)
> if (!pdev->dev.parent || pci_parent != pdev->dev.parent->of_node)
> continue;
>
> - if (!pci_match_id(pwrseq_m2_pci_ids, pdev))
> - continue;
> -
> - ret = pwrseq_pcie_m2_create_serdev_one(ctx, pdev);
> - if (ret) {
> - dev_err_probe(ctx->dev, ret,
> - "Failed to create serdev for PCI device (%s)\n",
> - pci_name(pdev));
> - pci_dev_put(pdev);
> - goto err_remove_serdev;
> + if (pci_match_id(pwrseq_m2_pci_ids, pdev)) {
> + ret = pwrseq_pcie_m2_create_serdev_one(ctx, pdev);
> + if (ret) {
> + dev_err_probe(ctx->dev, ret,
> + "Failed to create serdev for PCI device (%s)\n",
> + pci_name(pdev));
> + pci_dev_put(pdev);
> + goto err_remove_serdev;
> + }
> + } else if (ctx->w_disable2_gpio) {
> + gpiod_set_value_cansleep(ctx->w_disable2_gpio, 0);
> }
> }
>
[Severity: High]
Does this error path leak the hardware state if an error occurs after the
GPIO has been deasserted?
If pwrseq_pcie_m2_create_serdev() fails on a subsequent PCI device in the
loop, it jumps to err_remove_serdev. That cleanup path removes the UART
serdevs but does not appear to reset w_disable2_gpio to 1 for non-UART
devices.
Additionally, during driver removal in pwrseq_pcie_m2_remove(), the GPIO
is not symmetrically re-asserted. Can this leave the hardware permanently
powered on after driver unload?
[Severity: High]
This isn't a bug introduced by this patch, but is there a race condition
between iterating existing PCI devices and registering the notifier in
pwrseq_pcie_m2_probe()?
In pwrseq_pcie_m2_probe(), the code first invokes
pwrseq_pcie_m2_create_serdev() to handle existing devices, and then calls
pwrseq_pcie_m2_register_notifier().
If a PCI device is enumerated or hot-added in the narrow window between
these two statements, it seems it would be entirely missed, resulting in
missing hardware initialization.
Should the notifier be registered before iterating existing devices to
close this window?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260709-fix-hamoa-m2-w-disable2-v1-0-5e725091266a@oss.qualcomm.com?part=3
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH 3/3] power: sequencing: pcie-m2: Deassert W_DISABLE2# when no UART serdev is created
2026-07-09 7:29 ` [PATCH 3/3] power: sequencing: pcie-m2: Deassert W_DISABLE2# when no UART serdev is created Wei Deng
2026-07-09 7:44 ` sashiko-bot
@ 2026-07-09 7:56 ` Dmitry Baryshkov
1 sibling, 0 replies; 13+ messages in thread
From: Dmitry Baryshkov @ 2026-07-09 7:56 UTC (permalink / raw)
To: Wei Deng
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Manivannan Sadhasivam, Bartosz Golaszewski,
linux-arm-msm, devicetree, linux-kernel, linux-pci, linux-pm,
mengshi.wu
On Thu, Jul 09, 2026 at 12:59:42PM +0530, Wei Deng wrote:
> The pwrseq_m2_pci_ids[] table lists PCIe BT devices that use UART as the
> BT transport and need a UART serdev created by the driver. When a PCIe
> device under the M.2 connector does not match any entry in this table,
> no UART serdev is created.
>
> However, the BT subsystem of such a device may still require W_DISABLE2#
> to be deasserted to power up. Rather than adding every possible non-UART
> BT device ID to the table, add an else branch that deasserts W_DISABLE2#
> whenever a PCIe device is detected under the connector but does not match
> a UART BT entry. This allows any BT interface on the card (USB or other)
> to enumerate without requiring explicit knowledge of its device ID.
>
> The primary use case is USB BT variants of combo chips that share the
> same PCIe device ID as their UART counterpart (e.g. WCN7851 NCM865 USB,
> sub 0x3378, vs NCM865A UART, sub 0x337c): no UART serdev is needed, but
> W_DISABLE2# must be deasserted so the USB BT device can enumerate.
Instead of forcibly toggling it, would it be more sensible to tie pwrseq
into the USB too? The onboard-usb-dev implements the same idea (of
powering up the USB device), but it predates pwrseq.
> Reassert W_DISABLE2# symmetrically when the PCIe device is removed.
>
> Validated on Hamoa EVK (IQ-X7181-EVK) with WCN7851 NCM865 USB card
> (sub 0x3378): without this change GPIO116 (W_DISABLE2#) stays low and
> no BT interface appears; with this change GPIO116 is driven high and the
> USB BT device enumerates and comes up via btusb.
>
> Signed-off-by: Wei Deng <wei.deng@oss.qualcomm.com>
> ---
> drivers/power/sequencing/pwrseq-pcie-m2.c | 33 +++++++++++++++++++++----------
> 1 file changed, 23 insertions(+), 10 deletions(-)
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 0/3] power: sequencing: pcie-m2: Enable USB/UART BT coexistence on Hamoa EVK
2026-07-09 7:29 [PATCH 0/3] power: sequencing: pcie-m2: Enable USB/UART BT coexistence on Hamoa EVK Wei Deng
` (2 preceding siblings ...)
2026-07-09 7:29 ` [PATCH 3/3] power: sequencing: pcie-m2: Deassert W_DISABLE2# when no UART serdev is created Wei Deng
@ 2026-07-09 7:46 ` Dmitry Baryshkov
2026-07-09 8:12 ` Wei Deng
3 siblings, 1 reply; 13+ messages in thread
From: Dmitry Baryshkov @ 2026-07-09 7:46 UTC (permalink / raw)
To: Wei Deng
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Manivannan Sadhasivam, Bartosz Golaszewski,
linux-arm-msm, devicetree, linux-kernel, linux-pci, linux-pm,
mengshi.wu
On Thu, Jul 09, 2026 at 12:59:39PM +0530, Wei Deng wrote:
> M.2 combo chips expose Wi-Fi over PCIe and Bluetooth over either UART
> or USB, depending on the card variant. Both variants share the same PCIe
> device ID but use different sub-system IDs. The current driver uses bare
> PCI_DEVICE() matches that cover all sub-system IDs, so both variants
> trigger UART serdev creation — wrong for USB-only BT cards.
>
> This series fixes USB/UART BT coexistence by:
>
> 1. Narrowing WCN6855 and WCN7851 table entries to UART-only sub-system
> IDs so USB variants no longer trigger UART serdev creation.
>
> 2. Deasserting W_DISABLE2# for any PCIe device detected under the
> connector that does not match a UART BT entry, allowing the BT
> subsystem to power up and the USB BT interface to enumerate.
>
> 3. Describing the PCIe M.2 Key E connector on the Hamoa IoT EVK,
> adding w-disable2-gpios for software control of W_DISABLE2#.
>
> Validated on Hamoa IoT EVK (IQ-X7181-EVK) with multiple M.2 cards:
> UART BT (WCN6855, WCN7851, QCC2072) and USB BT (WCN6855, WCN7851)
> all work correctly.
>
> Signed-off-by: Wei Deng <wei.deng@oss.qualcomm.com>
> ---
> Wei Deng (3):
> arm64: dts: qcom: hamoa-iot-evk: Describe the PCIe M.2 Key E connector
> power: sequencing: pcie-m2: Match WCN6855 and WCN7851 UART BT variants by subdevice ID
> power: sequencing: pcie-m2: Deassert W_DISABLE2# when no UART serdev is created
What are the dependencies between patches?
>
> arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts | 129 ++++++++++-------------------
> arch/arm64/boot/dts/qcom/hamoa.dtsi | 1 +
> drivers/power/sequencing/pwrseq-pcie-m2.c | 39 ++++++---
> 3 files changed, 74 insertions(+), 95 deletions(-)
> ---
> base-commit: b9810cd75b9fb56a3425d391cba3f608502bd474
> change-id: 20260709-fix-hamoa-m2-w-disable2-0fe775072c74
>
> Best regards,
> --
> Wei Deng <wei.deng@oss.qualcomm.com>
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH 0/3] power: sequencing: pcie-m2: Enable USB/UART BT coexistence on Hamoa EVK
2026-07-09 7:46 ` [PATCH 0/3] power: sequencing: pcie-m2: Enable USB/UART BT coexistence on Hamoa EVK Dmitry Baryshkov
@ 2026-07-09 8:12 ` Wei Deng
0 siblings, 0 replies; 13+ messages in thread
From: Wei Deng @ 2026-07-09 8:12 UTC (permalink / raw)
To: dmitry.baryshkov
Cc: andersson, konradybcio, robh, krzk+dt, conor+dt, mani, brgl,
linux-arm-msm, devicetree, linux-kernel, linux-pci, linux-pm
On Thu, 9 Jul 2026, Dmitry Baryshkov wrote:
> What are the dependencies between patches?
Patches 2 and 3 are ordered: patch 2 narrows the table to UART-only
sub-IDs, which patch 3 depends on.
Patch 1 functionally depends on patches 2 and 3: USB M.2 BT will not
work on the Hamoa EVK without them.
--
Best Regards,
Wei Deng
^ permalink raw reply [flat|nested] 13+ messages in thread