[PATCH 8/9] Bluetooth: hci_qca: Add support for WCN7850 PCIe M.2 card

Manivannan Sadhasivam via B4 Relay posted 9 patches 2 months, 4 weeks ago
There is a newer version of this series
[PATCH 8/9] Bluetooth: hci_qca: Add support for WCN7850 PCIe M.2 card
Posted by Manivannan Sadhasivam via B4 Relay 2 months, 4 weeks ago
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>

The WCN7850 PCIe M.2 card connected to the UART controller exposes the
'WCN7850' serdev device and is controlled using the pwrseq framework.

Hence, add support for it in the driver. It reuses the existing
'qca_soc_data_wcn7850' driver data.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
 drivers/bluetooth/hci_qca.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 4cff4d9be3132561ee9bae4ddf2c8ac0bc13ecd7..09bfb3bba93698f496947775bf6b31f2f20279f1 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>
@@ -2344,6 +2345,9 @@ static int qca_serdev_probe(struct serdev_device *serdev)
 
 	qcadev->serdev_hu.serdev = serdev;
 	data = device_get_match_data(&serdev->dev);
+	if (!data && serdev->id)
+		data = (const struct qca_device_data *) serdev->id->driver_data;
+
 	serdev_device_set_drvdata(serdev, qcadev);
 	device_property_read_string_array(&serdev->dev, "firmware-name",
 					 qcadev->firmware_name, ARRAY_SIZE(qcadev->firmware_name));
@@ -2384,6 +2388,15 @@ static int qca_serdev_probe(struct serdev_device *serdev)
 	case QCA_WCN6855:
 	case QCA_WCN7850:
 	case QCA_WCN6750:
+		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))
+				qcadev->bt_power->pwrseq = NULL;
+			else
+				break;
+		}
+
 		if (!device_property_present(&serdev->dev, "enable-gpios")) {
 			/*
 			 * Backward compatibility with old DT sources. If the
@@ -2740,6 +2753,12 @@ static const struct acpi_device_id qca_bluetooth_acpi_match[] = {
 MODULE_DEVICE_TABLE(acpi, qca_bluetooth_acpi_match);
 #endif
 
+static const struct serdev_device_id qca_bluetooth_serdev_match[] = {
+	{ "WCN7850", (kernel_ulong_t)&qca_soc_data_wcn7850 },
+	{ },
+};
+MODULE_DEVICE_TABLE(serdev, qca_bluetooth_serdev_match);
+
 #ifdef CONFIG_DEV_COREDUMP
 static void hciqca_coredump(struct device *dev)
 {
@@ -2756,6 +2775,7 @@ static void hciqca_coredump(struct device *dev)
 static struct serdev_device_driver qca_serdev_driver = {
 	.probe = qca_serdev_probe,
 	.remove = qca_serdev_remove,
+	.id_table = qca_bluetooth_serdev_match,
 	.driver = {
 		.name = "hci_uart_qca",
 		.of_match_table = of_match_ptr(qca_bluetooth_of_match),

-- 
2.48.1
Re: [PATCH 8/9] Bluetooth: hci_qca: Add support for WCN7850 PCIe M.2 card
Posted by Bartosz Golaszewski 2 months, 3 weeks ago
On Wed, Nov 12, 2025 at 3:45 PM Manivannan Sadhasivam via B4 Relay
<devnull+manivannan.sadhasivam.oss.qualcomm.com@kernel.org> wrote:
>
> From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
>
> The WCN7850 PCIe M.2 card connected to the UART controller exposes the
> 'WCN7850' serdev device and is controlled using the pwrseq framework.
>
> Hence, add support for it in the driver. It reuses the existing
> 'qca_soc_data_wcn7850' driver data.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> ---
>  drivers/bluetooth/hci_qca.c | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
>
> diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
> index 4cff4d9be3132561ee9bae4ddf2c8ac0bc13ecd7..09bfb3bba93698f496947775bf6b31f2f20279f1 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>
> @@ -2344,6 +2345,9 @@ static int qca_serdev_probe(struct serdev_device *serdev)
>
>         qcadev->serdev_hu.serdev = serdev;
>         data = device_get_match_data(&serdev->dev);
> +       if (!data && serdev->id)
> +               data = (const struct qca_device_data *) serdev->id->driver_data;
> +
>         serdev_device_set_drvdata(serdev, qcadev);
>         device_property_read_string_array(&serdev->dev, "firmware-name",
>                                          qcadev->firmware_name, ARRAY_SIZE(qcadev->firmware_name));
> @@ -2384,6 +2388,15 @@ static int qca_serdev_probe(struct serdev_device *serdev)
>         case QCA_WCN6855:
>         case QCA_WCN7850:
>         case QCA_WCN6750:
> +               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))
> +                               qcadev->bt_power->pwrseq = NULL;
> +                       else
> +                               break;
> +               }

Did you by any chance copy this logic from commit: db0ff7e15923
("driver: bluetooth: hci_qca:fix unable to load the BT driver")? This
commit is wrong and it flew under my radar during the summer and I
never got around to fixing it. It doesn't take into account probe
deferral.

Bartosz

> +
>                 if (!device_property_present(&serdev->dev, "enable-gpios")) {
>                         /*
>                          * Backward compatibility with old DT sources. If the
> @@ -2740,6 +2753,12 @@ static const struct acpi_device_id qca_bluetooth_acpi_match[] = {
>  MODULE_DEVICE_TABLE(acpi, qca_bluetooth_acpi_match);
>  #endif
>
> +static const struct serdev_device_id qca_bluetooth_serdev_match[] = {
> +       { "WCN7850", (kernel_ulong_t)&qca_soc_data_wcn7850 },
> +       { },
> +};
> +MODULE_DEVICE_TABLE(serdev, qca_bluetooth_serdev_match);
> +
>  #ifdef CONFIG_DEV_COREDUMP
>  static void hciqca_coredump(struct device *dev)
>  {
> @@ -2756,6 +2775,7 @@ static void hciqca_coredump(struct device *dev)
>  static struct serdev_device_driver qca_serdev_driver = {
>         .probe = qca_serdev_probe,
>         .remove = qca_serdev_remove,
> +       .id_table = qca_bluetooth_serdev_match,
>         .driver = {
>                 .name = "hci_uart_qca",
>                 .of_match_table = of_match_ptr(qca_bluetooth_of_match),
>
> --
> 2.48.1
>
>
Re: [PATCH 8/9] Bluetooth: hci_qca: Add support for WCN7850 PCIe M.2 card
Posted by Manivannan Sadhasivam 2 months, 3 weeks ago
On Tue, Nov 18, 2025 at 03:29:49PM +0100, Bartosz Golaszewski wrote:
> On Wed, Nov 12, 2025 at 3:45 PM Manivannan Sadhasivam via B4 Relay
> <devnull+manivannan.sadhasivam.oss.qualcomm.com@kernel.org> wrote:
> >
> > From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> >
> > The WCN7850 PCIe M.2 card connected to the UART controller exposes the
> > 'WCN7850' serdev device and is controlled using the pwrseq framework.
> >
> > Hence, add support for it in the driver. It reuses the existing
> > 'qca_soc_data_wcn7850' driver data.
> >
> > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> > ---
> >  drivers/bluetooth/hci_qca.c | 20 ++++++++++++++++++++
> >  1 file changed, 20 insertions(+)
> >
> > diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
> > index 4cff4d9be3132561ee9bae4ddf2c8ac0bc13ecd7..09bfb3bba93698f496947775bf6b31f2f20279f1 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>
> > @@ -2344,6 +2345,9 @@ static int qca_serdev_probe(struct serdev_device *serdev)
> >
> >         qcadev->serdev_hu.serdev = serdev;
> >         data = device_get_match_data(&serdev->dev);
> > +       if (!data && serdev->id)
> > +               data = (const struct qca_device_data *) serdev->id->driver_data;
> > +
> >         serdev_device_set_drvdata(serdev, qcadev);
> >         device_property_read_string_array(&serdev->dev, "firmware-name",
> >                                          qcadev->firmware_name, ARRAY_SIZE(qcadev->firmware_name));
> > @@ -2384,6 +2388,15 @@ static int qca_serdev_probe(struct serdev_device *serdev)
> >         case QCA_WCN6855:
> >         case QCA_WCN7850:
> >         case QCA_WCN6750:
> > +               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))
> > +                               qcadev->bt_power->pwrseq = NULL;
> > +                       else
> > +                               break;
> > +               }
> 
> Did you by any chance copy this logic from commit: db0ff7e15923
> ("driver: bluetooth: hci_qca:fix unable to load the BT driver")? This
> commit is wrong and it flew under my radar during the summer and I
> never got around to fixing it. It doesn't take into account probe
> deferral.
> 

Ah, yes. I think there is no point in continuing if devm_pwrseq_get() errors
out.

- Mani

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