Re: [PATCH V7] Bluetooth: btnxpuart: Add M.2 Bluetooth device support using pwrseq
"Sherry Sun (OSS)" <[email protected]>
| Newsgroups | dev.linux.lists.imx,org.kernel.vger.linux-bluetooth,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <anKmfKB6T2dE9MCl@shlinux88> |
Hi Luiz, Gentle ping ... On Tue, Jul 21, 2026 at 11:04:58AM +0800, Sherry Sun (OSS) wrote: >From: Sherry Sun <[email protected]> > >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, pwrseq_power_on() is called to power up the M.2 Bluetooth >card. The power sequencer descriptor is obtained via pwrseq_get() with >the UART controller device (serdev->ctrl->dev), since the OF graph >link is defined on the UART controller node. > >Also add the explicit pwrseq_put() call in all exit paths, pwrseq_put() >already calls pwrseq_power_off() internally, so no separate >pwrseq_power_off() call is needed. > >Signed-off-by: Sherry Sun <[email protected]> >Reviewed-by: Bartosz Golaszewski <[email protected]> >Reviewed-by: Frank Li <[email protected]> >Reviewed-by: Manivannan Sadhasivam <[email protected]> >--- >Changes in V7: >1. Seperate this Bluetooth patch from the V6 M.2 patch set so that it >can be applied directly to bluetooth-next tree, no code change. >https://lore.kernel.org/all/[email protected]/ >--- > drivers/bluetooth/btnxpuart.c | 34 ++++++++++++++++++++++++++++++---- > 1 file changed, 30 insertions(+), 4 deletions(-) > >diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c >index 0bb300eef157..81a11ac05114 100644 >--- a/drivers/bluetooth/btnxpuart.c >+++ b/drivers/bluetooth/btnxpuart.c >@@ -9,6 +9,8 @@ > > #include <linux/serdev.h> > #include <linux/of.h> >+#include <linux/of_graph.h> >+#include <linux/pwrseq/consumer.h> > #include <linux/skbuff.h> > #include <linux/unaligned.h> > #include <linux/firmware.h> >@@ -211,6 +213,7 @@ struct btnxpuart_dev { > > struct ps_data psdata; > struct btnxpuart_data *nxp_data; >+ struct pwrseq_desc *pwrseq; > struct reset_control *pdn; > struct hci_uart hu; > }; >@@ -1872,11 +1875,26 @@ static int nxp_serdev_probe(struct serdev_device *serdev) > return err; > } > >+ if (of_graph_is_present(dev_of_node(&serdev->ctrl->dev))) { >+ struct pwrseq_desc *pwrseq; >+ >+ pwrseq = pwrseq_get(&serdev->ctrl->dev, "uart"); >+ if (IS_ERR(pwrseq)) >+ return dev_err_probe(&serdev->dev, PTR_ERR(pwrseq), >+ "failed to get pwrseq\n"); >+ >+ nxpdev->pwrseq = pwrseq; >+ err = pwrseq_power_on(pwrseq); >+ if (err) >+ goto err_pwrseq_put; >+ } >+ > /* Initialize and register HCI device */ > hdev = hci_alloc_dev(); > if (!hdev) { > dev_err(&serdev->dev, "Can't allocate HCI device\n"); >- return -ENOMEM; >+ err = -ENOMEM; >+ goto err_pwrseq_put; > } > > reset_control_deassert(nxpdev->pdn); >@@ -1907,13 +1925,16 @@ static int nxp_serdev_probe(struct serdev_device *serdev) > if (bacmp(&ba, BDADDR_ANY)) > hci_set_quirk(hdev, HCI_QUIRK_USE_BDADDR_PROPERTY); > >- if (hci_register_dev(hdev) < 0) { >+ err = hci_register_dev(hdev); >+ if (err < 0) { > dev_err(&serdev->dev, "Can't register HCI device\n"); > goto probe_fail; > } > >- if (ps_setup(hdev)) >+ if (ps_setup(hdev)) { >+ err = -ENODEV; > goto probe_fail_unregister; >+ } > > hci_devcd_register(hdev, nxp_coredump, nxp_coredump_hdr, > nxp_coredump_notify); >@@ -1925,7 +1946,10 @@ static int nxp_serdev_probe(struct serdev_device *serdev) > probe_fail: > reset_control_assert(nxpdev->pdn); > hci_free_dev(hdev); >- return -ENODEV; >+err_pwrseq_put: >+ if (nxpdev->pwrseq) >+ pwrseq_put(nxpdev->pwrseq); >+ return err; > } > > static void nxp_serdev_remove(struct serdev_device *serdev) >@@ -1952,6 +1976,8 @@ static void nxp_serdev_remove(struct serdev_device *serdev) > ps_cleanup(nxpdev); > hci_unregister_dev(hdev); > reset_control_assert(nxpdev->pdn); >+ if (nxpdev->pwrseq) >+ pwrseq_put(nxpdev->pwrseq); > hci_free_dev(hdev); > } > > >base-commit: 3fe08b9796f36ef437ab9328e7dd1e5ff2d66603 >-- >2.50.1 >