[PATCH] Bluetooth: btnxpuart: Check remote M.2 connector availability before pwrseq
"Sherry Sun (OSS)" <[email protected]>
| Newsgroups | org.kernel.vger.linux-bluetooth,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Sherry Sun <[email protected]> The current code uses of_graph_is_present() to decide whether to enter the pwrseq path. However, of_graph_is_present() only checks for the structural presence of a port/ports sub-node and does not check the status property. This causes problems when a DT overlay disables the remote M.2 connector node (e.g., switching from PCIe WiFi to SDIO WiFi): the port node still exists, so of_graph_is_present() returns true, but the pwrseq provider never registers because the connector is disabled, leading to an infinite -EPROBE_DEFER loop. Replace of_graph_is_present() with a new helper that traverses the OF graph to the remote port parent (the M.2 connector node) and checks of_device_is_available(). When the remote connector is disabled, the pwrseq path is skipped, allowing the BT driver to fall through to the direct bluetooth child node path. Fixes: 3c48135c1397 ("Bluetooth: btnxpuart: Add M.2 Bluetooth device support using pwrseq") Signed-off-by: Sherry Sun <[email protected]> --- drivers/bluetooth/btnxpuart.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c index 81cdd8da5636..e2b8f7997e4e 100644 --- a/drivers/bluetooth/btnxpuart.c +++ b/drivers/bluetooth/btnxpuart.c @@ -1809,6 +1809,28 @@ static void nxp_coredump_notify(struct hci_dev *hdev, int state) kobject_uevent_env(&serdev->dev.kobj, KOBJ_CHANGE, envp); } +/* + * Check if the remote M.2 connector device linked via OF graph is present + * and available. This is used to determine whether the pwrseq path should + * be taken. When the remote connector node is disabled (e.g., by a DT + * overlay switching from PCIe WiFi to SDIO WiFi), the pwrseq path is + * skipped, allowing the BT driver to use a direct bluetooth child node + * instead. + */ +static bool nxp_m2_connector_is_available(struct device *dev) +{ + struct device_node *ep __free(device_node) = + of_graph_get_next_endpoint(dev_of_node(dev), NULL); + + if (!ep) + return false; + + struct device_node *remote __free(device_node) = + of_graph_get_remote_port_parent(ep); + + return remote && of_device_is_available(remote); +} + static int nxp_serdev_probe(struct serdev_device *serdev) { struct hci_dev *hdev; @@ -1863,7 +1885,7 @@ static int nxp_serdev_probe(struct serdev_device *serdev) return err; } - if (of_graph_is_present(dev_of_node(&serdev->ctrl->dev))) { + if (nxp_m2_connector_is_available(&serdev->ctrl->dev)) { struct pwrseq_desc *pwrseq; pwrseq = pwrseq_get(&serdev->ctrl->dev, "uart"); --- base-commit: 4477a78374a57c3809b172ad30cceabda48c47c6 change-id: 20260817-btnxpuart_m2-a9814969871b Best regards, -- Sherry Sun <[email protected]>