Linux Serial subsystem development
 help / color / mirror / Atom feed
* [PATCH v6 9/9] power: sequencing: pcie-m2: Create serdev device for WCN7850 bluetooth
From: Manivannan Sadhasivam via B4 Relay @ 2026-03-17  4:29 UTC (permalink / raw)
  To: Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
	Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
	Derek J. Clark, Manivannan Sadhasivam, Krzysztof Kozlowski,
	Conor Dooley, Marcel Holtmann, Luiz Augusto von Dentz,
	Bartosz Golaszewski, Andy Shevchenko, Bartosz Golaszewski
  Cc: linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
	linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
	Stephan Gerhold, Dmitry Baryshkov, linux-acpi,
	Manivannan Sadhasivam, Hans de Goede
In-Reply-To: <20260317-pci-m2-e-v6-0-9c898f108d3d@oss.qualcomm.com>

From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>

For supporting bluetooth over the non-discoverable UART interface of
WCN7850, create the serdev device after enumerating the PCIe interface.
This is mandatory since the device ID is only known after the PCIe
enumeration and the ID is used for creating the serdev device.

Since by default there is no OF or ACPI node for the created serdev,
create a dynamic OF 'bluetooth' node with the 'compatible' property and
attach it to the serdev device. This will allow the serdev device to bind
to the existing bluetooth driver.

Tested-by: Hans de Goede <johannes.goede@oss.qualcomm.com> # ThinkPad T14s gen6 (arm64)
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
 drivers/power/sequencing/Kconfig          |   3 +-
 drivers/power/sequencing/pwrseq-pcie-m2.c | 178 +++++++++++++++++++++++++++++-
 2 files changed, 177 insertions(+), 4 deletions(-)

diff --git a/drivers/power/sequencing/Kconfig b/drivers/power/sequencing/Kconfig
index f5fff84566ba..55aeef125e6f 100644
--- a/drivers/power/sequencing/Kconfig
+++ b/drivers/power/sequencing/Kconfig
@@ -37,7 +37,8 @@ config POWER_SEQUENCING_TH1520_GPU
 
 config POWER_SEQUENCING_PCIE_M2
 	tristate "PCIe M.2 connector power sequencing driver"
-	depends on OF || COMPILE_TEST
+	depends on (PCI && OF) || COMPILE_TEST
+	select OF_DYNAMIC
 	help
 	  Say Y here to enable the power sequencing driver for PCIe M.2
 	  connectors. This driver handles the power sequencing for the M.2
diff --git a/drivers/power/sequencing/pwrseq-pcie-m2.c b/drivers/power/sequencing/pwrseq-pcie-m2.c
index 3507cdcb1e7b..77357439ba81 100644
--- a/drivers/power/sequencing/pwrseq-pcie-m2.c
+++ b/drivers/power/sequencing/pwrseq-pcie-m2.c
@@ -12,9 +12,11 @@
 #include <linux/of.h>
 #include <linux/of_graph.h>
 #include <linux/of_platform.h>
+#include <linux/pci.h>
 #include <linux/platform_device.h>
 #include <linux/pwrseq/provider.h>
 #include <linux/regulator/consumer.h>
+#include <linux/serdev.h>
 #include <linux/slab.h>
 
 struct pwrseq_pcie_m2_pdata {
@@ -30,6 +32,9 @@ struct pwrseq_pcie_m2_ctx {
 	struct notifier_block nb;
 	struct gpio_desc *w_disable1_gpio;
 	struct gpio_desc *w_disable2_gpio;
+	struct serdev_device *serdev;
+	struct of_changeset *ocs;
+	struct device *dev;
 };
 
 static int pwrseq_pcie_m2_vregs_enable(struct pwrseq_device *pwrseq)
@@ -172,13 +177,176 @@ static int pwrseq_pcie_m2_match(struct pwrseq_device *pwrseq,
 	return PWRSEQ_NO_MATCH;
 }
 
-static void pwrseq_pcie_m2_free_regulators(void *data)
+static void pwrseq_pcie_m2_free_resources(void *data)
 {
 	struct pwrseq_pcie_m2_ctx *ctx = data;
 
+	serdev_device_remove(ctx->serdev);
+	bus_unregister_notifier(&pci_bus_type, &ctx->nb);
+	of_changeset_revert(ctx->ocs);
+	of_changeset_destroy(ctx->ocs);
 	regulator_bulk_free(ctx->num_vregs, ctx->regs);
 }
 
+static int pwrseq_m2_pcie_create_bt_node(struct pwrseq_pcie_m2_ctx *ctx,
+					struct device_node *parent)
+{
+	struct device *dev = ctx->dev;
+	struct device_node *np;
+	int ret;
+
+	ctx->ocs = devm_kzalloc(dev, sizeof(*ctx->ocs), GFP_KERNEL);
+	if (!ctx->ocs)
+		return -ENOMEM;
+
+	of_changeset_init(ctx->ocs);
+
+	np = of_changeset_create_node(ctx->ocs, parent, "bluetooth");
+	if (!np) {
+		dev_err(dev, "Failed to create bluetooth node\n");
+		ret = -ENODEV;
+		goto err_destroy_changeset;
+	}
+
+	ret = of_changeset_add_prop_string(ctx->ocs, np, "compatible", "qcom,wcn7850-bt");
+	if (ret) {
+		dev_err(dev, "Failed to add bluetooth compatible: %d\n", ret);
+		goto err_destroy_changeset;
+	}
+
+	ret = of_changeset_apply(ctx->ocs);
+	if (ret) {
+		dev_err(dev, "Failed to apply changeset: %d\n", ret);
+		goto err_destroy_changeset;
+	}
+
+	ret = device_add_of_node(&ctx->serdev->dev, np);
+	if (ret) {
+		dev_err(dev, "Failed to add OF node: %d\n", ret);
+		goto err_revert_changeset;
+	}
+
+	return 0;
+
+err_revert_changeset:
+	of_changeset_revert(ctx->ocs);
+err_destroy_changeset:
+	of_changeset_destroy(ctx->ocs);
+
+	return ret;
+}
+
+static int pwrseq_m2_pcie_notify(struct notifier_block *nb, unsigned long action,
+			      void *data)
+{
+	struct pwrseq_pcie_m2_ctx *ctx = container_of(nb, struct pwrseq_pcie_m2_ctx, nb);
+	struct pci_dev *pdev = to_pci_dev(data);
+	struct serdev_controller *serdev_ctrl;
+	struct device *dev = ctx->dev;
+	int ret;
+
+	/*
+	 * Check whether the PCI device is associated with this M.2 connector or
+	 * not, by comparing the OF node of the PCI device parent and the Port 0
+	 * (PCIe) remote node parent OF node.
+	 */
+	struct device_node *pci_parent __free(device_node) =
+			of_graph_get_remote_node(dev_of_node(ctx->dev), 0, 0);
+	if (!pci_parent || (pci_parent != pdev->dev.parent->of_node))
+		return NOTIFY_DONE;
+
+	switch (action) {
+	case BUS_NOTIFY_ADD_DEVICE:
+		/* Create serdev device for WCN7850 */
+		if (pdev->vendor == PCI_VENDOR_ID_QCOM && pdev->device == 0x1107) {
+			struct device_node *serdev_parent __free(device_node) =
+				of_graph_get_remote_node(dev_of_node(ctx->dev), 1, 1);
+			if (!serdev_parent)
+				return NOTIFY_DONE;
+
+			serdev_ctrl = of_find_serdev_controller_by_node(serdev_parent);
+			if (!serdev_ctrl)
+				return NOTIFY_DONE;
+
+			/*
+			 * Bail out if the device was already attached to this
+			 * controller.
+			 */
+			if (serdev_ctrl->serdev)
+				return NOTIFY_DONE;
+
+			ctx->serdev = serdev_device_alloc(serdev_ctrl);
+			if (!ctx->serdev)
+				return NOTIFY_BAD;
+
+			ret = pwrseq_m2_pcie_create_bt_node(ctx, serdev_parent);
+			if (ret) {
+				serdev_device_put(ctx->serdev);
+				return notifier_from_errno(ret);
+			}
+
+			ret = serdev_device_add(ctx->serdev);
+			if (ret) {
+				dev_err(dev, "Failed to add serdev for WCN7850: %d\n", ret);
+				of_changeset_revert(ctx->ocs);
+				of_changeset_destroy(ctx->ocs);
+				serdev_device_put(ctx->serdev);
+				return notifier_from_errno(ret);
+			}
+		}
+		break;
+	case BUS_NOTIFY_REMOVED_DEVICE:
+		/* Destroy serdev device for WCN7850 */
+		if (pdev->vendor == PCI_VENDOR_ID_QCOM && pdev->device == 0x1107) {
+			serdev_device_remove(ctx->serdev);
+			of_changeset_revert(ctx->ocs);
+			of_changeset_destroy(ctx->ocs);
+		}
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
+static bool pwrseq_pcie_m2_check_remote_node(struct device *dev, u8 port, u8 endpoint,
+					     const char *node)
+{
+	struct device_node *remote __free(device_node) =
+			of_graph_get_remote_node(dev_of_node(dev), port, endpoint);
+
+	if (remote && of_node_name_eq(remote, node))
+		return true;
+
+	return false;
+}
+
+/*
+ * If the connector exposes a non-discoverable bus like UART, the respective
+ * protocol device needs to be created manually with the help of the notifier
+ * of the discoverable bus like PCIe.
+ */
+static int pwrseq_pcie_m2_register_notifier(struct pwrseq_pcie_m2_ctx *ctx, struct device *dev)
+{
+	int ret;
+
+	/*
+	 * Register a PCI notifier for Key E connector that has PCIe as Port
+	 * 0/Endpoint 0 interface and Serial as Port 3/Endpoint 0 interface.
+	 */
+	if (pwrseq_pcie_m2_check_remote_node(dev, 3, 0, "serial")) {
+		if (pwrseq_pcie_m2_check_remote_node(dev, 0, 0, "pcie")) {
+			ctx->dev = dev;
+			ctx->nb.notifier_call = pwrseq_m2_pcie_notify;
+			ret = bus_register_notifier(&pci_bus_type, &ctx->nb);
+			if (ret)
+				return dev_err_probe(dev, ret,
+						     "Failed to register notifier for serdev\n");
+		}
+	}
+
+	return 0;
+}
+
 static int pwrseq_pcie_m2_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -218,7 +386,7 @@ static int pwrseq_pcie_m2_probe(struct platform_device *pdev)
 
 	ctx->num_vregs = ret;
 
-	ret = devm_add_action_or_reset(dev, pwrseq_pcie_m2_free_regulators, ctx);
+	ret = devm_add_action_or_reset(dev, pwrseq_pcie_m2_free_resources, ctx);
 	if (ret)
 		return ret;
 
@@ -233,7 +401,11 @@ static int pwrseq_pcie_m2_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, PTR_ERR(ctx->pwrseq),
 				     "Failed to register the power sequencer\n");
 
-	return 0;
+	/*
+	 * Register a notifier for creating protocol devices for
+	 * non-discoverable busses like UART.
+	 */
+	return pwrseq_pcie_m2_register_notifier(ctx, dev);
 }
 
 static const struct of_device_id pwrseq_pcie_m2_of_match[] = {

-- 
2.51.0



^ permalink raw reply related

* [PATCH v6 7/9] Bluetooth: hci_qca: Add M.2 Bluetooth device support using pwrseq
From: Manivannan Sadhasivam via B4 Relay @ 2026-03-17  4:29 UTC (permalink / raw)
  To: Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
	Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
	Derek J. Clark, Manivannan Sadhasivam, Krzysztof Kozlowski,
	Conor Dooley, Marcel Holtmann, Luiz Augusto von Dentz,
	Bartosz Golaszewski, Andy Shevchenko, Bartosz Golaszewski
  Cc: linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
	linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
	Stephan Gerhold, Dmitry Baryshkov, linux-acpi,
	Manivannan Sadhasivam, Hans de Goede, Bartosz Golaszewski
In-Reply-To: <20260317-pci-m2-e-v6-0-9c898f108d3d@oss.qualcomm.com>

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.

Tested-by: Hans de Goede <johannes.goede@oss.qualcomm.com> # ThinkPad T14s gen6 (arm64)
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
 drivers/bluetooth/hci_qca.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 5b02e7c3f56d..0454c2318461 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>
@@ -2421,6 +2422,14 @@ 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))
+				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.51.0



^ permalink raw reply related

* [PATCH v6 5/9] dt-bindings: connector: Add PCIe M.2 Mechanical Key E connector
From: Manivannan Sadhasivam via B4 Relay @ 2026-03-17  4:29 UTC (permalink / raw)
  To: Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
	Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
	Derek J. Clark, Manivannan Sadhasivam, Krzysztof Kozlowski,
	Conor Dooley, Marcel Holtmann, Luiz Augusto von Dentz,
	Bartosz Golaszewski, Andy Shevchenko, Bartosz Golaszewski
  Cc: linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
	linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
	Stephan Gerhold, Dmitry Baryshkov, linux-acpi,
	Manivannan Sadhasivam
In-Reply-To: <20260317-pci-m2-e-v6-0-9c898f108d3d@oss.qualcomm.com>

From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>

Add the devicetree binding for PCIe M.2 Mechanical Key E connector defined
in the PCI Express M.2 Specification, r4.0, sec 5.1.2. This connector
provides interfaces like PCIe or SDIO to attach the WiFi devices to the
host machine, USB or UART+PCM interfaces to attach the Bluetooth (BT)
devices. Spec also provides an optional interface to connect the UIM card,
but that is not covered in this binding.

The connector provides a primary power supply of 3.3v, along with an
optional 1.8v VIO supply for the Adapter I/O buffer circuitry operating at
1.8v sideband signaling.

The connector also supplies optional signals in the form of GPIOs for fine
grained power management.

Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
 .../bindings/connector/pcie-m2-e-connector.yaml    | 184 +++++++++++++++++++++
 MAINTAINERS                                        |   1 +
 2 files changed, 185 insertions(+)

diff --git a/Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml b/Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml
new file mode 100644
index 000000000000..f7859aa9b634
--- /dev/null
+++ b/Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml
@@ -0,0 +1,184 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/connector/pcie-m2-e-connector.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: PCIe M.2 Mechanical Key E Connector
+
+maintainers:
+  - Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
+
+description:
+  A PCIe M.2 E connector node represents a physical PCIe M.2 Mechanical Key E
+  connector. Mechanical Key E connectors are used to connect Wireless
+  Connectivity devices including combinations of Wi-Fi, BT, NFC to the host
+  machine over interfaces like PCIe/SDIO, USB/UART+PCM, and I2C.
+
+properties:
+  compatible:
+    const: pcie-m2-e-connector
+
+  vpcie3v3-supply:
+    description: A phandle to the regulator for 3.3v supply.
+
+  vpcie1v8-supply:
+    description: A phandle to the regulator for VIO 1.8v supply.
+
+  i2c-parent:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: I2C interface
+
+  clocks:
+    description: 32.768 KHz Suspend Clock (SUSCLK) input from the host system to
+      the M.2 card. Refer, PCI Express M.2 Specification r4.0, sec 3.1.12.1 for
+      more details.
+    maxItems: 1
+
+  w-disable1-gpios:
+    description: GPIO output to W_DISABLE1# signal. This signal is used by the
+      host system to disable WiFi radio in the M.2 card. Refer, PCI Express M.2
+      Specification r4.0, sec 3.1.12.3 for more details.
+    maxItems: 1
+
+  w-disable2-gpios:
+    description: GPIO output to W_DISABLE2# signal. This signal is used by the
+      host system to disable BT radio in the M.2 card. Refer, PCI Express M.2
+      Specification r4.0, sec 3.1.12.3 for more details.
+    maxItems: 1
+
+  viocfg-gpios:
+    description: GPIO input to IO voltage configuration (VIO_CFG) signal. The
+      card drives this signal to indicate to the host system whether the card
+      supports an independent IO voltage domain for sideband signals. Refer,
+      PCI Express M.2 Specification r4.0, sec 3.1.15.1 for more details.
+    maxItems: 1
+
+  uart-wake-gpios:
+    description: GPIO input to UART_WAKE# signal. The card asserts this signal
+      to wake the host system and initiate UART interface communication. Refer,
+      PCI Express M.2 Specification r4.0, sec 3.1.8.1 for more details.
+    maxItems: 1
+
+  sdio-wake-gpios:
+    description: GPIO input to SDIO_WAKE# signal. The card asserts this signal
+      to wake the host system and initiate SDIO interface communication. Refer,
+      PCI Express M.2 Specification r4.0, sec 3.1.7 for more details.
+    maxItems: 1
+
+  sdio-reset-gpios:
+    description: GPIO output to SDIO_RESET# signal. This signal is used by the
+      host system to reset SDIO interface of the M.2 card. Refer, PCI Express
+      M.2 Specification r4.0, sec 3.1.7 for more details.
+    maxItems: 1
+
+  vendor-porta-gpios:
+    description: GPIO for the first vendor specific signal (VENDOR_PORTA). This
+      signal's functionality is defined by the card manufacturer and may be
+      used for proprietary features. Refer the card vendor's documentation for
+      details.
+    maxItems: 1
+
+  vendor-portb-gpios:
+    description: GPIO for the second vendor specific signal (VENDOR_PORTB). This
+      signal's functionality is defined by the card manufacturer and may be
+      used for proprietary features. Refer the card vendor's documentation for
+      details.
+    maxItems: 1
+
+  vendor-portc-gpios:
+    description: GPIO for the third vendor specific signal (VENDOR_PORTC). This
+      signal's functionality is defined by the card manufacturer and may be
+      used for proprietary features. Refer the card vendor's documentation for
+      details.
+    maxItems: 1
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+    description: OF graph bindings modeling the interfaces exposed on the
+      connector. Since a single connector can have multiple interfaces, every
+      interface has an assigned OF graph port number as described below.
+
+    properties:
+      port@0:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: PCIe interface for Wi-Fi
+
+      port@1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: SDIO interface for Wi-Fi
+
+      port@2:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: USB 2.0 interface for BT
+
+      port@3:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: UART interface for BT
+
+      port@4:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: PCM/I2S interface
+
+    anyOf:
+      - anyOf:
+          - required:
+              - port@0
+          - required:
+              - port@1
+      - anyOf:
+          - required:
+              - port@2
+          - required:
+              - port@3
+
+required:
+  - compatible
+  - vpcie3v3-supply
+
+additionalProperties: false
+
+examples:
+  # PCI M.2 Key E connector for Wi-Fi/BT with PCIe/UART interfaces
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    connector {
+        compatible = "pcie-m2-e-connector";
+        vpcie3v3-supply = <&vreg_wcn_3p3>;
+        vpcie1v8-supply = <&vreg_l15b_1p8>;
+        i2c-parent = <&i2c0>;
+        w-disable1-gpios = <&tlmm 115 GPIO_ACTIVE_LOW>;
+        w-disable2-gpios = <&tlmm 116 GPIO_ACTIVE_LOW>;
+        viocfg-gpios = <&tlmm 117 GPIO_ACTIVE_HIGH>;
+        uart-wake-gpios = <&tlmm 118 GPIO_ACTIVE_LOW>;
+        sdio-wake-gpios = <&tlmm 119 GPIO_ACTIVE_LOW>;
+        sdio-reset-gpios = <&tlmm 120 GPIO_ACTIVE_LOW>;
+
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port@0 {
+                reg = <0>;
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                endpoint@0 {
+                    reg = <0>;
+                    remote-endpoint = <&pcie4_port0_ep>;
+                };
+            };
+
+            port@3 {
+                reg = <3>;
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                endpoint@0 {
+                    reg = <0>;
+                    remote-endpoint = <&uart14_ep>;
+                };
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 55af015174a5..565198d3b500 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21044,6 +21044,7 @@ PCIE M.2 POWER SEQUENCING
 M:	Manivannan Sadhasivam <mani@kernel.org>
 L:	linux-pci@vger.kernel.org
 S:	Maintained
+F:	Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml
 F:	Documentation/devicetree/bindings/connector/pcie-m2-m-connector.yaml
 F:	drivers/power/sequencing/pwrseq-pcie-m2.c
 

-- 
2.51.0



^ permalink raw reply related

* [PATCH v6 8/9] power: sequencing: pcie-m2: Add support for PCIe M.2 Key E connectors
From: Manivannan Sadhasivam via B4 Relay @ 2026-03-17  4:29 UTC (permalink / raw)
  To: Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
	Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
	Derek J. Clark, Manivannan Sadhasivam, Krzysztof Kozlowski,
	Conor Dooley, Marcel Holtmann, Luiz Augusto von Dentz,
	Bartosz Golaszewski, Andy Shevchenko, Bartosz Golaszewski
  Cc: linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
	linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
	Stephan Gerhold, Dmitry Baryshkov, linux-acpi,
	Manivannan Sadhasivam, Hans de Goede
In-Reply-To: <20260317-pci-m2-e-v6-0-9c898f108d3d@oss.qualcomm.com>

From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>

Add support for handling the power sequence of the PCIe M.2 Key E
connectors. These connectors are used to attach the Wireless Connectivity
devices to the host machine including combinations of WiFi, BT, NFC using
interfaces such as PCIe/SDIO for WiFi, USB/UART for BT and I2C for NFC.

Currently, this driver supports only the PCIe interface for WiFi and UART
interface for BT. The driver also only supports driving the 3.3v/1.8v power
supplies and W_DISABLE{1/2}# GPIOs. The optional signals of the Key E
connectors are not currently supported.

Tested-by: Hans de Goede <johannes.goede@oss.qualcomm.com> # ThinkPad T14s gen6 (arm64)
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
 drivers/power/sequencing/pwrseq-pcie-m2.c | 107 ++++++++++++++++++++++++++++--
 1 file changed, 101 insertions(+), 6 deletions(-)

diff --git a/drivers/power/sequencing/pwrseq-pcie-m2.c b/drivers/power/sequencing/pwrseq-pcie-m2.c
index d31a7dd8b35c..3507cdcb1e7b 100644
--- a/drivers/power/sequencing/pwrseq-pcie-m2.c
+++ b/drivers/power/sequencing/pwrseq-pcie-m2.c
@@ -5,10 +5,13 @@
  */
 
 #include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
 #include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_graph.h>
+#include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/pwrseq/provider.h>
 #include <linux/regulator/consumer.h>
@@ -25,16 +28,18 @@ struct pwrseq_pcie_m2_ctx {
 	struct regulator_bulk_data *regs;
 	size_t num_vregs;
 	struct notifier_block nb;
+	struct gpio_desc *w_disable1_gpio;
+	struct gpio_desc *w_disable2_gpio;
 };
 
-static int pwrseq_pcie_m2_m_vregs_enable(struct pwrseq_device *pwrseq)
+static int pwrseq_pcie_m2_vregs_enable(struct pwrseq_device *pwrseq)
 {
 	struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
 
 	return regulator_bulk_enable(ctx->num_vregs, ctx->regs);
 }
 
-static int pwrseq_pcie_m2_m_vregs_disable(struct pwrseq_device *pwrseq)
+static int pwrseq_pcie_m2_vregs_disable(struct pwrseq_device *pwrseq)
 {
 	struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
 
@@ -43,18 +48,84 @@ static int pwrseq_pcie_m2_m_vregs_disable(struct pwrseq_device *pwrseq)
 
 static const struct pwrseq_unit_data pwrseq_pcie_m2_vregs_unit_data = {
 	.name = "regulators-enable",
-	.enable = pwrseq_pcie_m2_m_vregs_enable,
-	.disable = pwrseq_pcie_m2_m_vregs_disable,
+	.enable = pwrseq_pcie_m2_vregs_enable,
+	.disable = pwrseq_pcie_m2_vregs_disable,
 };
 
-static const struct pwrseq_unit_data *pwrseq_pcie_m2_m_unit_deps[] = {
+static const struct pwrseq_unit_data *pwrseq_pcie_m2_unit_deps[] = {
 	&pwrseq_pcie_m2_vregs_unit_data,
 	NULL
 };
 
+static int pwrseq_pci_m2_e_uart_enable(struct pwrseq_device *pwrseq)
+{
+	struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
+
+	return gpiod_set_value_cansleep(ctx->w_disable2_gpio, 0);
+}
+
+static int pwrseq_pci_m2_e_uart_disable(struct pwrseq_device *pwrseq)
+{
+	struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
+
+	return gpiod_set_value_cansleep(ctx->w_disable2_gpio, 1);
+}
+
+static const struct pwrseq_unit_data pwrseq_pcie_m2_e_uart_unit_data = {
+	.name = "uart-enable",
+	.deps = pwrseq_pcie_m2_unit_deps,
+	.enable = pwrseq_pci_m2_e_uart_enable,
+	.disable = pwrseq_pci_m2_e_uart_disable,
+};
+
+static int pwrseq_pci_m2_e_pcie_enable(struct pwrseq_device *pwrseq)
+{
+	struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
+
+	return gpiod_set_value_cansleep(ctx->w_disable1_gpio, 0);
+}
+
+static int pwrseq_pci_m2_e_pcie_disable(struct pwrseq_device *pwrseq)
+{
+	struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
+
+	return gpiod_set_value_cansleep(ctx->w_disable1_gpio, 1);
+}
+
+static const struct pwrseq_unit_data pwrseq_pcie_m2_e_pcie_unit_data = {
+	.name = "pcie-enable",
+	.deps = pwrseq_pcie_m2_unit_deps,
+	.enable = pwrseq_pci_m2_e_pcie_enable,
+	.disable = pwrseq_pci_m2_e_pcie_disable,
+};
+
 static const struct pwrseq_unit_data pwrseq_pcie_m2_m_pcie_unit_data = {
 	.name = "pcie-enable",
-	.deps = pwrseq_pcie_m2_m_unit_deps,
+	.deps = pwrseq_pcie_m2_unit_deps,
+};
+
+static int pwrseq_pcie_m2_e_pwup_delay(struct pwrseq_device *pwrseq)
+{
+	/*
+	 * FIXME: This delay is only required for some Qcom WLAN/BT cards like
+	 * WCN7850 and not for all devices. But currently, there is no way to
+	 * identify the device model before enumeration.
+	 */
+	msleep(50);
+
+	return 0;
+}
+
+static const struct pwrseq_target_data pwrseq_pcie_m2_e_uart_target_data = {
+	.name = "uart",
+	.unit = &pwrseq_pcie_m2_e_uart_unit_data,
+	.post_enable = pwrseq_pcie_m2_e_pwup_delay,
+};
+
+static const struct pwrseq_target_data pwrseq_pcie_m2_e_pcie_target_data = {
+	.name = "pcie",
+	.unit = &pwrseq_pcie_m2_e_pcie_unit_data,
+	.post_enable = pwrseq_pcie_m2_e_pwup_delay,
 };
 
 static const struct pwrseq_target_data pwrseq_pcie_m2_m_pcie_target_data = {
@@ -62,11 +133,21 @@ static const struct pwrseq_target_data pwrseq_pcie_m2_m_pcie_target_data = {
 	.unit = &pwrseq_pcie_m2_m_pcie_unit_data,
 };
 
+static const struct pwrseq_target_data *pwrseq_pcie_m2_e_targets[] = {
+	&pwrseq_pcie_m2_e_pcie_target_data,
+	&pwrseq_pcie_m2_e_uart_target_data,
+	NULL
+};
+
 static const struct pwrseq_target_data *pwrseq_pcie_m2_m_targets[] = {
 	&pwrseq_pcie_m2_m_pcie_target_data,
 	NULL
 };
 
+static const struct pwrseq_pcie_m2_pdata pwrseq_pcie_m2_e_of_data = {
+	.targets = pwrseq_pcie_m2_e_targets,
+};
+
 static const struct pwrseq_pcie_m2_pdata pwrseq_pcie_m2_m_of_data = {
 	.targets = pwrseq_pcie_m2_m_targets,
 };
@@ -125,6 +206,16 @@ static int pwrseq_pcie_m2_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, ret,
 				     "Failed to get all regulators\n");
 
+	ctx->w_disable1_gpio = devm_gpiod_get_optional(dev, "w-disable1", GPIOD_OUT_HIGH);
+	if (IS_ERR(ctx->w_disable1_gpio))
+		return dev_err_probe(dev, PTR_ERR(ctx->w_disable1_gpio),
+				     "Failed to get the W_DISABLE_1# GPIO\n");
+
+	ctx->w_disable2_gpio = devm_gpiod_get_optional(dev, "w-disable2", GPIOD_OUT_HIGH);
+	if (IS_ERR(ctx->w_disable2_gpio))
+		return dev_err_probe(dev, PTR_ERR(ctx->w_disable2_gpio),
+				     "Failed to get the W_DISABLE_2# GPIO\n");
+
 	ctx->num_vregs = ret;
 
 	ret = devm_add_action_or_reset(dev, pwrseq_pcie_m2_free_regulators, ctx);
@@ -150,6 +241,10 @@ static const struct of_device_id pwrseq_pcie_m2_of_match[] = {
 		.compatible = "pcie-m2-m-connector",
 		.data = &pwrseq_pcie_m2_m_of_data,
 	},
+	{
+		.compatible = "pcie-m2-e-connector",
+		.data = &pwrseq_pcie_m2_e_of_data,
+	},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, pwrseq_pcie_m2_of_match);

-- 
2.51.0



^ permalink raw reply related

* [PATCH v6 6/9] dt-bindings: connector: m2: Add M.2 1620 LGA soldered down connector
From: Manivannan Sadhasivam via B4 Relay @ 2026-03-17  4:29 UTC (permalink / raw)
  To: Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
	Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
	Derek J. Clark, Manivannan Sadhasivam, Krzysztof Kozlowski,
	Conor Dooley, Marcel Holtmann, Luiz Augusto von Dentz,
	Bartosz Golaszewski, Andy Shevchenko, Bartosz Golaszewski
  Cc: linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
	linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
	Stephan Gerhold, Dmitry Baryshkov, linux-acpi,
	Manivannan Sadhasivam
In-Reply-To: <20260317-pci-m2-e-v6-0-9c898f108d3d@oss.qualcomm.com>

From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>

Lenovo Thinkpad T14s is found to have a soldered down version of M.2 1620
LGA connector. Though, there is no 1620 LGA form factor defined in the M.2
spec, it looks very similar to the M.2 Key E connector. So add the
"pcie-m2-1620-lga-connector" compatible with "pcie-m2-e-connector" fallback
to reuse the Key E binding.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
 .../devicetree/bindings/connector/pcie-m2-e-connector.yaml       | 9 ++++++++-
 1 file changed, 8 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 f7859aa9b634..d8cf9a9ec7d0 100644
--- a/Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml
+++ b/Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml
@@ -17,7 +17,14 @@ description:
 
 properties:
   compatible:
-    const: pcie-m2-e-connector
+    oneOf:
+      - items:
+          - enum:
+              - pcie-m2-1620-lga-connector
+          - const: pcie-m2-e-connector
+      - items:
+          - enum:
+              - pcie-m2-e-connector
 
   vpcie3v3-supply:
     description: A phandle to the regulator for 3.3v supply.

-- 
2.51.0



^ permalink raw reply related

* [PATCH v6 3/9] serdev: Do not return -ENODEV from of_serdev_register_devices() if external connector is used
From: Manivannan Sadhasivam via B4 Relay @ 2026-03-17  4:29 UTC (permalink / raw)
  To: Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
	Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
	Derek J. Clark, Manivannan Sadhasivam, Krzysztof Kozlowski,
	Conor Dooley, Marcel Holtmann, Luiz Augusto von Dentz,
	Bartosz Golaszewski, Andy Shevchenko, Bartosz Golaszewski
  Cc: linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
	linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
	Stephan Gerhold, Dmitry Baryshkov, linux-acpi,
	Manivannan Sadhasivam, Hans de Goede, Bartosz Golaszewski
In-Reply-To: <20260317-pci-m2-e-v6-0-9c898f108d3d@oss.qualcomm.com>

From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>

If an external connector like M.2 is connected to the serdev controller
in DT, then the serdev devices may be created dynamically by the connector
driver. So do not return -ENODEV from of_serdev_register_devices() if the
static nodes are not found and the graph node is used.

Tested-by: Hans de Goede <johannes.goede@oss.qualcomm.com> # ThinkPad T14s gen6 (arm64)
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
 drivers/tty/serdev/core.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index bf88b95f7458..e9d044a331b0 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 #include <linux/of_device.h>
 #include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
@@ -561,7 +562,13 @@ static int of_serdev_register_devices(struct serdev_controller *ctrl)
 		} else
 			found = true;
 	}
-	if (!found)
+
+	/*
+	 * When the serdev controller is connected to an external connector like
+	 * M.2 in DT, then the serdev devices may be created dynamically by the
+	 * connector driver.
+	 */
+	if (!found && !of_graph_is_present(dev_of_node(&ctrl->dev)))
 		return -ENODEV;
 
 	return 0;

-- 
2.51.0



^ permalink raw reply related

* [PATCH v6 2/9] serdev: Add an API to find the serdev controller associated with the devicetree node
From: Manivannan Sadhasivam via B4 Relay @ 2026-03-17  4:29 UTC (permalink / raw)
  To: Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
	Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
	Derek J. Clark, Manivannan Sadhasivam, Krzysztof Kozlowski,
	Conor Dooley, Marcel Holtmann, Luiz Augusto von Dentz,
	Bartosz Golaszewski, Andy Shevchenko, Bartosz Golaszewski
  Cc: linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
	linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
	Stephan Gerhold, Dmitry Baryshkov, linux-acpi,
	Manivannan Sadhasivam, Hans de Goede, Bartosz Golaszewski
In-Reply-To: <20260317-pci-m2-e-v6-0-9c898f108d3d@oss.qualcomm.com>

From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>

Add of_find_serdev_controller_by_node() API to find the serdev controller
device associated with the devicetree node.

Tested-by: Hans de Goede <johannes.goede@oss.qualcomm.com> # ThinkPad T14s gen6 (arm64)
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
 drivers/tty/serdev/core.c | 19 +++++++++++++++++++
 include/linux/serdev.h    |  9 +++++++++
 2 files changed, 28 insertions(+)

diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index 8f25510f89b6..bf88b95f7458 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -514,6 +514,25 @@ struct serdev_controller *serdev_controller_alloc(struct device *host,
 }
 EXPORT_SYMBOL_GPL(serdev_controller_alloc);
 
+#ifdef CONFIG_OF
+/**
+ * of_find_serdev_controller_by_node() - Find the serdev controller associated
+ *					 with the devicetree node
+ * @node:	Devicetree node
+ *
+ * Return: Pointer to the serdev controller associated with the node. NULL if
+ * the controller is not found. Caller is responsible for calling
+ * serdev_controller_put() to drop the reference.
+ */
+struct serdev_controller *of_find_serdev_controller_by_node(struct device_node *node)
+{
+	struct device *dev = bus_find_device_by_of_node(&serdev_bus_type, node);
+
+	return (dev && dev->type == &serdev_ctrl_type) ? to_serdev_controller(dev) : NULL;
+}
+EXPORT_SYMBOL_GPL(of_find_serdev_controller_by_node);
+#endif
+
 static int of_serdev_register_devices(struct serdev_controller *ctrl)
 {
 	struct device_node *node;
diff --git a/include/linux/serdev.h b/include/linux/serdev.h
index 0c7d3c27d1f8..188c0ba62d50 100644
--- a/include/linux/serdev.h
+++ b/include/linux/serdev.h
@@ -334,4 +334,13 @@ static inline bool serdev_acpi_get_uart_resource(struct acpi_resource *ares,
 }
 #endif /* CONFIG_ACPI */
 
+#ifdef CONFIG_OF
+struct serdev_controller *of_find_serdev_controller_by_node(struct device_node *node);
+#else
+static inline struct serdev_controller *of_find_serdev_controller_by_node(struct device_node *node)
+{
+	return NULL;
+}
+#endif /* CONFIG_OF */
+
 #endif /*_LINUX_SERDEV_H */

-- 
2.51.0



^ permalink raw reply related

* [PATCH v6 0/9] Add support for handling PCIe M.2 Key E connectors in devicetree
From: Manivannan Sadhasivam via B4 Relay @ 2026-03-17  4:29 UTC (permalink / raw)
  To: Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
	Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
	Derek J. Clark, Manivannan Sadhasivam, Krzysztof Kozlowski,
	Conor Dooley, Marcel Holtmann, Luiz Augusto von Dentz,
	Bartosz Golaszewski, Andy Shevchenko, Bartosz Golaszewski
  Cc: linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
	linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
	Stephan Gerhold, Dmitry Baryshkov, linux-acpi,
	Manivannan Sadhasivam, Hans de Goede, Bartosz Golaszewski,
	Bartosz Golaszewski

Hi,

This series is the continuation of the series [1] that added the initial support
for the PCIe M.2 connectors. This series extends it by adding support for Key E
connectors. These connectors are used to connect the Wireless Connectivity
devices such as WiFi, BT, NFC and GNSS devices to the host machine over
interfaces such as PCIe/SDIO, USB/UART and NFC. This series adds support for
connectors that expose PCIe interface for WiFi and UART interface for BT. Other
interfaces are left for future improvements.

Serdev device support for BT
============================

Adding support for the PCIe interface was mostly straightforward and a lot
similar to the previous Key M connector. But adding UART interface has proved to
be tricky. This is mostly because of the fact UART is a non-discoverable bus,
unlike PCIe which is discoverable. So this series relied on the PCI notifier to
create the serdev device for UART/BT. This means the PCIe interface will be
brought up first and after the PCIe device enumeration, the serdev device will
be created by the pwrseq driver. This logic is necessary since the connector
driver and DT node don't describe the device, but just the connector. So to make
the connector interface Plug and Play, the connector driver uses the PCIe device
ID to identify the card and creates the serdev device. This logic could be
extended in the future to support more M.2 cards. Even if the M.2 card uses SDIO
interface for connecting WLAN, a SDIO notifier could be added to create the
serdev device.

Testing
=======

This series, together with the devicetree changes [2] was tested on the
Qualcomm X1e based Lenovo Thinkpad T14s Laptop which has the WCN7850 WLAN/BT
1620 LGA card connected over PCIe and UART.

Merge Strategy
==============

Due to the API dependency, both the serdev and pwrseq patches need to go through
a single tree, maybe through pwrseq tree. So the serdev patches need Ack from
Greg. But Bluetooth patch can be merged separately.

[1] https://lore.kernel.org/linux-pci/20260107-pci-m2-v5-0-8173d8a72641@oss.qualcomm.com
[2] https://github.com/Mani-Sadhasivam/linux/commit/b50f8386900990eed3dce8d91c3b643fb0e8739d

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
Changes in v6:
- Added a check to bail out if the serdev device was already added during notifier.
- Collected tags
- Link to v5: https://lore.kernel.org/r/20260224-pci-m2-e-v5-0-dd9b9501d33c@oss.qualcomm.com

Changes in v5:
- Incorporated comments in the binding patch by using single endpoint per port,
  reordering port nodes, adding missing properties and using a complete example.
- Incorporated comments in the pwrseq patch (nothing major)
- Fixed the build issue in patch 2
- Collected tags
- Rebased on top of 7.0-rc1
- Link to v4: https://lore.kernel.org/r/20260112-pci-m2-e-v4-0-eff84d2c6d26@oss.qualcomm.com

Changes in v4:
- Switched to dynamic OF node for serdev instead of swnode and dropped all
  swnode related patches
- Link to v3: https://lore.kernel.org/r/20260110-pci-m2-e-v3-0-4faee7d0d5ae@oss.qualcomm.com

Changes in v3:
- Switched to swnode for the serdev device and dropped the custom
  serdev_device_id related patches
- Added new swnode APIs to match the swnode with existing of_device_id
- Incorporated comments in the bindings patch
- Dropped the UIM interface from binding since it is not clear how it should get
  wired
- Incorporated comments in the pwrseq driver patch
- Splitted the pwrseq patch into two
- Added the 1620 LGA compatible with Key E fallback based on Stephan's finding
- Link to v2: https://lore.kernel.org/r/20251125-pci-m2-e-v2-0-32826de07cc5@oss.qualcomm.com

Changes in v2:
- Used '-' for GPIO names in the binding and removed led*-gpios properties
- Described the endpoint nodes for port@0 and port@1 nodes
- Added the OF graph port to the serial binding
- Fixed the hci_qca driver to return err if devm_pwrseq_get() fails
- Incorporated various review comments in pwrseq driver
- Collected Ack
- Link to v1: https://lore.kernel.org/r/20251112-pci-m2-e-v1-0-97413d6bf824@oss.qualcomm.com

---
Manivannan Sadhasivam (9):
      serdev: Convert to_serdev_*() helpers to macros and use container_of_const()
      serdev: Add an API to find the serdev controller associated with the devicetree node
      serdev: Do not return -ENODEV from of_serdev_register_devices() if external connector is used
      dt-bindings: serial: Document the graph port
      dt-bindings: connector: Add PCIe M.2 Mechanical Key E connector
      dt-bindings: connector: m2: Add M.2 1620 LGA soldered down connector
      Bluetooth: hci_qca: Add M.2 Bluetooth device support using pwrseq
      power: sequencing: pcie-m2: Add support for PCIe M.2 Key E connectors
      power: sequencing: pcie-m2: Create serdev device for WCN7850 bluetooth

 .../bindings/connector/pcie-m2-e-connector.yaml    | 191 ++++++++++++++
 .../devicetree/bindings/serial/serial.yaml         |   3 +
 MAINTAINERS                                        |   1 +
 drivers/bluetooth/hci_qca.c                        |   9 +
 drivers/power/sequencing/Kconfig                   |   3 +-
 drivers/power/sequencing/pwrseq-pcie-m2.c          | 285 ++++++++++++++++++++-
 drivers/tty/serdev/core.c                          |  28 +-
 include/linux/serdev.h                             |  24 +-
 8 files changed, 521 insertions(+), 23 deletions(-)
---
base-commit: 559f264e403e4d58d56a17595c60a1de011c5e20
change-id: 20251112-pci-m2-e-94695ac9d657

Best regards,
-- 
Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>



^ permalink raw reply

* [PATCH v6 1/9] serdev: Convert to_serdev_*() helpers to macros and use container_of_const()
From: Manivannan Sadhasivam via B4 Relay @ 2026-03-17  4:29 UTC (permalink / raw)
  To: Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
	Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
	Derek J. Clark, Manivannan Sadhasivam, Krzysztof Kozlowski,
	Conor Dooley, Marcel Holtmann, Luiz Augusto von Dentz,
	Bartosz Golaszewski, Andy Shevchenko, Bartosz Golaszewski
  Cc: linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
	linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
	Stephan Gerhold, Dmitry Baryshkov, linux-acpi,
	Manivannan Sadhasivam, Hans de Goede, Bartosz Golaszewski
In-Reply-To: <20260317-pci-m2-e-v6-0-9c898f108d3d@oss.qualcomm.com>

From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>

If these helpers receive the 'const struct device' pointer, then the const
qualifier will get dropped, leading to below warning:

warning: passing argument 1 of ‘to_serdev_device_driver’ discards 'const'
qualifier from pointer target type [-Wdiscarded-qualifiers]

This is not an issue as of now, but with the future commits adding serdev
device based driver matching, this warning will get triggered. Hence,
convert these helpers to macros so that the qualifier get preserved and
also use container_of_const() as container_of() is deprecated.

Tested-by: Hans de Goede <johannes.goede@oss.qualcomm.com> # ThinkPad T14s gen6 (arm64)
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
 include/linux/serdev.h | 15 +++------------
 1 file changed, 3 insertions(+), 12 deletions(-)

diff --git a/include/linux/serdev.h b/include/linux/serdev.h
index 5654c58eb73c..0c7d3c27d1f8 100644
--- a/include/linux/serdev.h
+++ b/include/linux/serdev.h
@@ -49,10 +49,7 @@ struct serdev_device {
 	struct mutex write_lock;
 };
 
-static inline struct serdev_device *to_serdev_device(struct device *d)
-{
-	return container_of(d, struct serdev_device, dev);
-}
+#define to_serdev_device(d) container_of_const(d, struct serdev_device, dev)
 
 /**
  * struct serdev_device_driver - serdev slave device driver
@@ -68,10 +65,7 @@ struct serdev_device_driver {
 	void	(*shutdown)(struct serdev_device *);
 };
 
-static inline struct serdev_device_driver *to_serdev_device_driver(struct device_driver *d)
-{
-	return container_of(d, struct serdev_device_driver, driver);
-}
+#define to_serdev_device_driver(d) container_of_const(d, struct serdev_device_driver, driver)
 
 enum serdev_parity {
 	SERDEV_PARITY_NONE,
@@ -112,10 +106,7 @@ struct serdev_controller {
 	const struct serdev_controller_ops *ops;
 };
 
-static inline struct serdev_controller *to_serdev_controller(struct device *d)
-{
-	return container_of(d, struct serdev_controller, dev);
-}
+#define to_serdev_controller(d) container_of_const(d, struct serdev_controller, dev)
 
 static inline void *serdev_device_get_drvdata(const struct serdev_device *serdev)
 {

-- 
2.51.0



^ permalink raw reply related

* [PATCH v6 4/9] dt-bindings: serial: Document the graph port
From: Manivannan Sadhasivam via B4 Relay @ 2026-03-17  4:29 UTC (permalink / raw)
  To: Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
	Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
	Derek J. Clark, Manivannan Sadhasivam, Krzysztof Kozlowski,
	Conor Dooley, Marcel Holtmann, Luiz Augusto von Dentz,
	Bartosz Golaszewski, Andy Shevchenko, Bartosz Golaszewski
  Cc: linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
	linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
	Stephan Gerhold, Dmitry Baryshkov, linux-acpi,
	Manivannan Sadhasivam, Bartosz Golaszewski
In-Reply-To: <20260317-pci-m2-e-v6-0-9c898f108d3d@oss.qualcomm.com>

From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>

A serial controller could be connected to an external connector like PCIe
M.2 for controlling the serial interface of the card. Hence, document the
OF graph port.

Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
 Documentation/devicetree/bindings/serial/serial.yaml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/serial/serial.yaml b/Documentation/devicetree/bindings/serial/serial.yaml
index 6aa9cfae417b..96eb1de8771e 100644
--- a/Documentation/devicetree/bindings/serial/serial.yaml
+++ b/Documentation/devicetree/bindings/serial/serial.yaml
@@ -87,6 +87,9 @@ properties:
     description:
       TX FIFO threshold configuration (in bytes).
 
+  port:
+    $ref: /schemas/graph.yaml#/properties/port
+
 patternProperties:
   "^(bluetooth|bluetooth-gnss|embedded-controller|gnss|gps|mcu|onewire)$":
     if:

-- 
2.51.0



^ permalink raw reply related

* Re: [PATCH v5 9/9] power: sequencing: pcie-m2: Create serdev device for WCN7850 bluetooth
From: Manivannan Sadhasivam @ 2026-03-17  4:18 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: manivannan.sadhasivam, linux-serial, linux-kernel, linux-kbuild,
	platform-driver-x86, linux-pci, devicetree, linux-arm-msm,
	linux-bluetooth, linux-pm, Stephan Gerhold, Dmitry Baryshkov,
	linux-acpi, Hans de Goede, Rob Herring, Greg Kroah-Hartman,
	Jiri Slaby, Nathan Chancellor, Nicolas Schier, Hans de Goede,
	Ilpo Järvinen, Mark Pearson, Derek J. Clark,
	Krzysztof Kozlowski, Conor Dooley, Marcel Holtmann,
	Luiz Augusto von Dentz, Bartosz Golaszewski, Andy Shevchenko,
	Manivannan Sadhasivam via B4 Relay
In-Reply-To: <CAMRc=MeJP-BLf3_zM9b+nz1nMOGVzyUhXemejHkV+AJREGPz_w@mail.gmail.com>

On Wed, Feb 25, 2026 at 03:22:50AM -0800, Bartosz Golaszewski wrote:
> On Tue, 24 Feb 2026 06:30:55 +0100, Manivannan Sadhasivam via B4 Relay
> <devnull+manivannan.sadhasivam.oss.qualcomm.com@kernel.org> said:
> > From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> >
> > For supporting bluetooth over the non-discoverable UART interface of
> > WCN7850, create the serdev device after enumerating the PCIe interface.
> > This is mandatory since the device ID is only known after the PCIe
> > enumeration and the ID is used for creating the serdev device.
> >
> > Since by default there is no OF or ACPI node for the created serdev,
> > create a dynamic OF 'bluetooth' node with the 'compatible' property and
> > attach it to the serdev device. This will allow the serdev device to bind
> > to the existing bluetooth driver.
> >
> > Tested-by: Hans de Goede <johannes.goede@oss.qualcomm.com> # ThinkPad T14s gen6 (arm64)
> > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> > ---
> >
> 
> [snip]
> 
> > -static void pwrseq_pcie_m2_free_regulators(void *data)
> > +static void pwrseq_pcie_m2_free_resources(void *data)
> >  {
> >  	struct pwrseq_pcie_m2_ctx *ctx = data;
> >
> > +	serdev_device_remove(ctx->serdev);
> > +	bus_unregister_notifier(&pci_bus_type, &ctx->nb);
> > +	of_changeset_revert(ctx->ocs);
> > +	of_changeset_destroy(ctx->ocs);
> >  	regulator_bulk_free(ctx->num_vregs, ctx->regs);
> >  }
> >
> > +static int pwrseq_m2_pcie_create_bt_node(struct pwrseq_pcie_m2_ctx *ctx,
> > +					struct device_node *parent)
> > +{
> > +	struct device *dev = ctx->dev;
> > +	struct device_node *np;
> > +	int ret;
> > +
> > +	ctx->ocs = devm_kzalloc(dev, sizeof(*ctx->ocs), GFP_KERNEL);
> > +	if (!ctx->ocs)
> > +		return -ENOMEM;
> > +
> > +	of_changeset_init(ctx->ocs);
> > +
> > +	np = of_changeset_create_node(ctx->ocs, parent, "bluetooth");
> > +	if (!np) {
> > +		dev_err(dev, "Failed to create bluetooth node\n");
> > +		ret = -ENODEV;
> > +		goto err_destroy_changeset;
> > +	}
> > +
> > +	ret = of_changeset_add_prop_string(ctx->ocs, np, "compatible", "qcom,wcn7850-bt");
> > +	if (ret) {
> > +		dev_err(dev, "Failed to add bluetooth compatible: %d\n", ret);
> > +		goto err_destroy_changeset;
> > +	}
> > +
> > +	ret = of_changeset_apply(ctx->ocs);
> > +	if (ret) {
> > +		dev_err(dev, "Failed to apply changeset: %d\n", ret);
> > +		goto err_destroy_changeset;
> > +	}
> > +
> > +	ret = device_add_of_node(&ctx->serdev->dev, np);
> > +	if (ret) {
> > +		dev_err(dev, "Failed to add OF node: %d\n", ret);
> > +		goto err_revert_changeset;
> > +	}
> > +
> > +	return 0;
> > +
> > +err_revert_changeset:
> > +	of_changeset_revert(ctx->ocs);
> > +err_destroy_changeset:
> > +	of_changeset_destroy(ctx->ocs);
> > +
> 
> I would prefer pwrseq_pcie_m2_free_resources() to be split into separate
> devm actions, otherwise it's not much different from simply having the
> .remove() callback. With a split like that you'd avoid having these labels
> here.
> 

We do need these error labels since pwrseq_m2_pcie_create_bt_node() is called
from notifier callback and a failure here doesn't cause the driver to fail. So
the changeset will linger till the driver gets removed.

So I don't see a real need to split pwrseq_pcie_m2_free_resources().

- Mani

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

^ permalink raw reply

* Re: [PATCH] tty: n_tty: annotate lockless read of ldata->icanon in input_available_p()
From: kernel test robot @ 2026-03-16 22:20 UTC (permalink / raw)
  To: Ziyu Zhang, Greg Kroah-Hartman, Jiri Slaby
  Cc: llvm, oe-kbuild-all, linux-kernel, linux-serial, baijiaju1990,
	r33s3n6, gality369, zhenghaoran154, hanguidong02, zzzccc427,
	Ziyu Zhang
In-Reply-To: <20260316132827.17855-1-ziyuzhang201@gmail.com>

Hi Ziyu,

kernel test robot noticed the following build errors:

[auto build test ERROR on tty/tty-testing]
[also build test ERROR on tty/tty-next tty/tty-linus linus/master v6.16-rc1 next-20260316]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Ziyu-Zhang/tty-n_tty-annotate-lockless-read-of-ldata-icanon-in-input_available_p/20260316-224221
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-testing
patch link:    https://lore.kernel.org/r/20260316132827.17855-1-ziyuzhang201%40gmail.com
patch subject: [PATCH] tty: n_tty: annotate lockless read of ldata->icanon in input_available_p()
config: x86_64-kexec (https://download.01.org/0day-ci/archive/20260316/202603162328.vY9JOJWL-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260316/202603162328.vY9JOJWL-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603162328.vY9JOJWL-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/tty/n_tty.c:1913:6: error: cannot pass bit-field as __auto_type initializer in C
    1913 |         if (data_race(ldata->icanon) && !L_EXTPROC(tty))
         |             ^
   include/linux/compiler.h:194:13: note: expanded from macro 'data_race'
     194 |         auto __v = (expr);                                              \
         |                    ^
   1 error generated.


vim +1913 drivers/tty/n_tty.c

  1906	
  1907	static inline int input_available_p(const struct tty_struct *tty, int poll)
  1908	{
  1909		const struct n_tty_data *ldata = tty->disc_data;
  1910		int amt = poll && !TIME_CHAR(tty) && MIN_CHAR(tty) ? MIN_CHAR(tty) : 1;
  1911	
  1912		/* data_race: benign race, poll readiness is best-effort */
> 1913		if (data_race(ldata->icanon) && !L_EXTPROC(tty))
  1914			return ldata->canon_head != ldata->read_tail;
  1915		else
  1916			return ldata->commit_head - ldata->read_tail >= amt;
  1917	}
  1918	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* [PATCH] tty: n_tty: annotate lockless read of ldata->icanon in input_available_p()
From: Ziyu Zhang @ 2026-03-16 13:28 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: linux-kernel, linux-serial, baijiaju1990, r33s3n6, gality369,
	zhenghaoran154, hanguidong02, zzzccc427, Ziyu Zhang

n_tty_poll() calls input_available_p() without holding termios_rwsem to
check input readiness for select()/poll(). input_available_p() reads
ldata->icanon, which can be concurrently written by n_tty_set_termios()
under down_write(termios_rwsem).

This is a benign race: poll/select readiness is best-effort, and the
actual n_tty_read() path re-checks icanon under down_read(termios_rwsem).
A stale icanon value in poll only causes a transiently incorrect
readiness result, which is permitted by POSIX poll/select semantics.

Since icanon is a bitfield, READ_ONCE()/WRITE_ONCE() cannot be used.
Annotate the read with data_race() to document the intentional lockless
access and suppress data race detector warnings.

Signed-off-by: Ziyu Zhang <ziyuzhang201@gmail.com>
---
 drivers/tty/n_tty.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index e6a0f5b40..aa3c11623 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -1909,7 +1909,8 @@ static inline int input_available_p(const struct tty_struct *tty, int poll)
 	const struct n_tty_data *ldata = tty->disc_data;
 	int amt = poll && !TIME_CHAR(tty) && MIN_CHAR(tty) ? MIN_CHAR(tty) : 1;
 
-	if (ldata->icanon && !L_EXTPROC(tty))
+	/* data_race: benign race, poll readiness is best-effort */
+	if (data_race(ldata->icanon) && !L_EXTPROC(tty))
 		return ldata->canon_head != ldata->read_tail;
 	else
 		return ldata->commit_head - ldata->read_tail >= amt;
-- 
2.39.5 (Apple Git-154)


^ permalink raw reply related

* [tty:tty-testing] BUILD SUCCESS eb3b0d92c9c39890592cca6647601fe5c631efea
From: kernel test robot @ 2026-03-16 12:26 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: linux-serial

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-testing
branch HEAD: eb3b0d92c9c39890592cca6647601fe5c631efea  tty: tty_port: add workqueue to flip TTY buffer

elapsed time: 1030m

configs tested: 55
configs skipped: 0

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
alpha         allnoconfig    gcc-15.2.0
alpha        allyesconfig    gcc-15.2.0
arc          allmodconfig    gcc-15.2.0
arc           allnoconfig    gcc-15.2.0
arc          allyesconfig    gcc-15.2.0
arm           allnoconfig    clang-23
arm          allyesconfig    gcc-15.2.0
arm64        allmodconfig    clang-19
arm64         allnoconfig    gcc-15.2.0
csky         allmodconfig    gcc-15.2.0
csky          allnoconfig    gcc-15.2.0
hexagon      allmodconfig    clang-17
hexagon       allnoconfig    clang-23
i386         allmodconfig    gcc-14
i386          allnoconfig    gcc-14
i386         allyesconfig    gcc-14
loongarch    allmodconfig    clang-19
loongarch     allnoconfig    clang-23
m68k         allmodconfig    gcc-15.2.0
m68k          allnoconfig    gcc-15.2.0
m68k         allyesconfig    gcc-15.2.0
microblaze    allnoconfig    gcc-15.2.0
microblaze   allyesconfig    gcc-15.2.0
mips         allmodconfig    gcc-15.2.0
mips          allnoconfig    gcc-15.2.0
mips         allyesconfig    gcc-15.2.0
nios2        allmodconfig    gcc-11.5.0
nios2         allnoconfig    gcc-11.5.0
openrisc     allmodconfig    gcc-15.2.0
openrisc      allnoconfig    gcc-15.2.0
parisc       allmodconfig    gcc-15.2.0
parisc        allnoconfig    gcc-15.2.0
parisc       allyesconfig    gcc-15.2.0
powerpc      allmodconfig    gcc-15.2.0
powerpc       allnoconfig    gcc-15.2.0
riscv        allmodconfig    clang-23
riscv         allnoconfig    gcc-15.2.0
riscv        allyesconfig    clang-16
s390         allmodconfig    clang-18
s390          allnoconfig    clang-23
s390         allyesconfig    gcc-15.2.0
sh           allmodconfig    gcc-15.2.0
sh            allnoconfig    gcc-15.2.0
sh           allyesconfig    gcc-15.2.0
sparc         allnoconfig    gcc-15.2.0
sparc64      allmodconfig    clang-23
um           allmodconfig    clang-19
um            allnoconfig    clang-23
um           allyesconfig    gcc-14
x86_64       allmodconfig    clang-20
x86_64        allnoconfig    clang-20
x86_64       allyesconfig    clang-20
x86_64      rhel-9.4-rust    clang-20
xtensa        allnoconfig    gcc-15.2.0
xtensa       allyesconfig    gcc-15.2.0

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* Re: [PATCH v2 2/2] riscv: ultrarisc: 8250_dw: support DP1000 uart
From: Andy Shevchenko @ 2026-03-16 11:35 UTC (permalink / raw)
  To: wangjia
  Cc: Ilpo Järvinen, Greg Kroah-Hartman, Jiri Slaby, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-kernel, linux-serial,
	linux-riscv, devicetree, Zhang Xincheng
In-Reply-To: <20260316-ultrarisc-serial-v2-2-6ab3e7fa891c@ultrarisc.com>

On Mon, Mar 16, 2026 at 02:33:23PM +0800, Jia Wang via B4 Relay wrote:

> The UART of DP1000 does not support automatic detection of
> buffer size. skip_autocfg needs to be set to true

Missed period at the end.


...

> +#define DW_UART_QUIRK_FIXED_TYPE	BIT(6)

Seems unrequired.

But to make sure, can you elaborate what's going on here?
What is the reads from UCV and CPR registers?

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply

* Re: [PATCH 1/2] riscv: ultrarisc: 8250_dw: support DP1000 uart
From: Conor Dooley @ 2026-03-16 11:22 UTC (permalink / raw)
  To: Jia Wang
  Cc: Ilpo Järvinen, Andy Shevchenko, Greg Kroah-Hartman,
	Jiri Slaby, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	linux-kernel, linux-serial, linux-riscv, devicetree,
	Zhang Xincheng
In-Reply-To: <20260316-ultrarisc-serial-v1-1-c464f3e933a5@ultrarisc.com>

[-- Attachment #1: Type: text/plain, Size: 2778 bytes --]

On Mon, Mar 16, 2026 at 09:36:18AM +0800, Jia Wang wrote:
> From: Zhang Xincheng <zhangxincheng@ultrarisc.com>
> 
> The UART of DP1000 does not support automatic detection of
> buffer size. skip_autocfg needs to be set to true
> 
> Signed-off-by: Zhang Xincheng <zhangxincheng@ultrarisc.com>
> Signed-off-by: Jia Wang <wangjia@ultrarisc.com>

$subject: riscv: ultrarisc: 8250_dw: support DP1000 uart

Please update this to match other modifications to this file.
"riscv: ultrariscv" doesn't belong at the start.

> ---
>  drivers/tty/serial/8250/8250_dw.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
> index db73b2ae17fa..6a2acf173331 100644
> --- a/drivers/tty/serial/8250/8250_dw.c
> +++ b/drivers/tty/serial/8250/8250_dw.c
> @@ -56,6 +56,7 @@
>  #define DW_UART_QUIRK_IS_DMA_FC		BIT(3)
>  #define DW_UART_QUIRK_APMC0D08		BIT(4)
>  #define DW_UART_QUIRK_CPR_VALUE		BIT(5)
> +#define DW_UART_QUIRK_FIXED_TYPE	BIT(6)
>  
>  struct dw8250_platform_data {
>  	u8 usr_reg;
> @@ -514,6 +515,11 @@ static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data)
>  		data->data.dma.prepare_tx_dma = dw8250_prepare_tx_dma;
>  		data->data.dma.prepare_rx_dma = dw8250_prepare_rx_dma;
>  	}
> +	if (quirks & DW_UART_QUIRK_FIXED_TYPE) {
> +		p->flags |= UPF_FIXED_TYPE;
> +		p->type = PORT_16550A;
> +		data->skip_autocfg = true;
> +	}
>  	if (quirks & DW_UART_QUIRK_APMC0D08) {
>  		p->iotype = UPIO_MEM32;
>  		p->regshift = 2;
> @@ -789,6 +795,11 @@ static const struct dw8250_platform_data dw8250_skip_set_rate_data = {
>  	.quirks = DW_UART_QUIRK_SKIP_SET_RATE,
>  };
>  
> +static const struct dw8250_platform_data dw8250_ultrarisc_dp1000_data = {
> +	.usr_reg = DW_UART_USR,
> +	.quirks = DW_UART_QUIRK_FIXED_TYPE,
> +};
> +
>  static const struct of_device_id dw8250_of_match[] = {
>  	{ .compatible = "snps,dw-apb-uart", .data = &dw8250_dw_apb },
>  	{ .compatible = "cavium,octeon-3860-uart", .data = &dw8250_octeon_3860_data },
> @@ -796,6 +807,7 @@ static const struct of_device_id dw8250_of_match[] = {
>  	{ .compatible = "renesas,rzn1-uart", .data = &dw8250_renesas_rzn1_data },
>  	{ .compatible = "sophgo,sg2044-uart", .data = &dw8250_skip_set_rate_data },
>  	{ .compatible = "starfive,jh7100-uart", .data = &dw8250_skip_set_rate_data },
> +	{ .compatible = "ultrarisc,dp1000-uart", .data = &dw8250_ultrarisc_dp1000_data },
>  	{ /* Sentinel */ }
>  };
>  MODULE_DEVICE_TABLE(of, dw8250_of_match);
> 
> -- 
> 2.34.1
> 
> 
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [PATCH 2/2] dt-bindings: serial: update bindings of ultrarisc dp1000 uart
From: Conor Dooley @ 2026-03-16 11:20 UTC (permalink / raw)
  To: Jia Wang
  Cc: Ilpo Järvinen, Andy Shevchenko, Greg Kroah-Hartman,
	Jiri Slaby, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	linux-kernel, linux-serial, linux-riscv, devicetree
In-Reply-To: <20260316-ultrarisc-serial-v1-2-c464f3e933a5@ultrarisc.com>

[-- Attachment #1: Type: text/plain, Size: 1148 bytes --]

On Mon, Mar 16, 2026 at 09:36:19AM +0800, Jia Wang wrote:
> Add UltraRISC vendor-prefix information
> Add DP1000 UART compatible information

$subject: update bindings of ultrarisc dp1000 uart

You're not updating, you're adding it.

> 
> Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
> ---
>  Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml
> index 6efe43089a74..0040ed28e35b 100644
> --- a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml
> +++ b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml
> @@ -78,6 +78,8 @@ properties:
>                - starfive,jh7100-uart
>                - starfive,jh7110-uart
>            - const: snps,dw-apb-uart
> +      - items:
> +          - const: ultrarisc,dp1000-uart
>        - const: snps,dw-apb-uart


This doesn't look right to me. An items list with one const is just the
same as having "const", like the snps,dw-apb-uart entry below it.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* [tty:tty-linus] BUILD SUCCESS 5eb608319bb56464674a71b4a66ea65c6c435d64
From: kernel test robot @ 2026-03-16  8:24 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: linux-serial

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-linus
branch HEAD: 5eb608319bb56464674a71b4a66ea65c6c435d64  vt: save/restore unicode screen buffer for alternate screen

elapsed time: 789m

configs tested: 168
configs skipped: 2

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
alpha                             allnoconfig    gcc-15.2.0
alpha                            allyesconfig    gcc-15.2.0
alpha                               defconfig    gcc-15.2.0
arc                              allmodconfig    clang-16
arc                               allnoconfig    gcc-15.2.0
arc                              allyesconfig    clang-23
arc                                 defconfig    gcc-15.2.0
arc                   randconfig-001-20260316    clang-23
arc                   randconfig-002-20260316    clang-23
arm                               allnoconfig    gcc-15.2.0
arm                              allyesconfig    clang-16
arm                                 defconfig    gcc-15.2.0
arm                   randconfig-001-20260316    clang-23
arm                   randconfig-002-20260316    clang-23
arm                   randconfig-003-20260316    clang-23
arm                   randconfig-004-20260316    clang-23
arm64                            allmodconfig    clang-23
arm64                             allnoconfig    gcc-15.2.0
arm64                               defconfig    gcc-15.2.0
arm64                 randconfig-001-20260316    clang-23
arm64                 randconfig-002-20260316    clang-23
arm64                 randconfig-003-20260316    clang-23
arm64                 randconfig-004-20260316    clang-23
csky                             allmodconfig    gcc-15.2.0
csky                              allnoconfig    gcc-15.2.0
csky                                defconfig    gcc-15.2.0
csky                  randconfig-001-20260316    clang-23
csky                  randconfig-002-20260316    clang-23
hexagon                          allmodconfig    gcc-15.2.0
hexagon                           allnoconfig    gcc-15.2.0
hexagon                             defconfig    gcc-15.2.0
hexagon               randconfig-001-20260316    gcc-11.5.0
hexagon               randconfig-002-20260316    gcc-11.5.0
i386                             allmodconfig    clang-20
i386                              allnoconfig    gcc-15.2.0
i386                             allyesconfig    clang-20
i386        buildonly-randconfig-001-20260316    gcc-14
i386        buildonly-randconfig-002-20260316    gcc-14
i386        buildonly-randconfig-003-20260316    gcc-14
i386        buildonly-randconfig-004-20260316    gcc-14
i386        buildonly-randconfig-005-20260316    gcc-14
i386        buildonly-randconfig-006-20260316    gcc-14
i386                                defconfig    gcc-15.2.0
i386                  randconfig-001-20260316    gcc-14
i386                  randconfig-002-20260316    gcc-14
i386                  randconfig-003-20260316    gcc-14
i386                  randconfig-004-20260316    gcc-14
i386                  randconfig-005-20260316    gcc-14
i386                  randconfig-006-20260316    gcc-14
i386                  randconfig-007-20260316    gcc-14
i386                  randconfig-011-20260316    gcc-13
i386                  randconfig-012-20260316    gcc-13
i386                  randconfig-013-20260316    gcc-13
i386                  randconfig-014-20260316    gcc-13
i386                  randconfig-015-20260316    gcc-13
i386                  randconfig-016-20260316    gcc-13
i386                  randconfig-017-20260316    gcc-13
loongarch                        allmodconfig    clang-23
loongarch                         allnoconfig    gcc-15.2.0
loongarch                           defconfig    clang-19
loongarch             randconfig-001-20260316    gcc-11.5.0
loongarch             randconfig-002-20260316    gcc-11.5.0
m68k                             allmodconfig    gcc-15.2.0
m68k                              allnoconfig    gcc-15.2.0
m68k                             allyesconfig    clang-16
m68k                                defconfig    clang-19
microblaze                        allnoconfig    gcc-15.2.0
microblaze                       allyesconfig    gcc-15.2.0
microblaze                          defconfig    clang-19
mips                             allmodconfig    gcc-15.2.0
mips                              allnoconfig    gcc-15.2.0
mips                             allyesconfig    gcc-15.2.0
nios2                            allmodconfig    clang-23
nios2                             allnoconfig    clang-23
nios2                               defconfig    clang-19
nios2                 randconfig-001-20260316    gcc-11.5.0
nios2                 randconfig-002-20260316    gcc-11.5.0
openrisc                         allmodconfig    clang-23
openrisc                          allnoconfig    clang-23
openrisc                            defconfig    gcc-15.2.0
parisc                           allmodconfig    gcc-15.2.0
parisc                            allnoconfig    clang-23
parisc                           allyesconfig    clang-19
parisc                              defconfig    gcc-15.2.0
parisc                randconfig-001-20260316    gcc-13.4.0
parisc                randconfig-002-20260316    gcc-13.4.0
parisc64                            defconfig    clang-19
powerpc                          allmodconfig    gcc-15.2.0
powerpc                           allnoconfig    clang-23
powerpc               randconfig-001-20260316    gcc-13.4.0
powerpc               randconfig-002-20260316    gcc-13.4.0
powerpc64             randconfig-001-20260316    gcc-13.4.0
powerpc64             randconfig-002-20260316    gcc-13.4.0
riscv                            allmodconfig    clang-23
riscv                             allnoconfig    clang-23
riscv                            allyesconfig    clang-16
riscv                               defconfig    gcc-15.2.0
riscv                 randconfig-001-20260316    gcc-12.5.0
riscv                 randconfig-002-20260316    gcc-12.5.0
s390                             allmodconfig    clang-19
s390                              allnoconfig    clang-23
s390                             allyesconfig    gcc-15.2.0
s390                                defconfig    gcc-15.2.0
s390                  randconfig-001-20260316    gcc-12.5.0
s390                  randconfig-002-20260316    gcc-12.5.0
sh                               allmodconfig    gcc-15.2.0
sh                                allnoconfig    clang-23
sh                               allyesconfig    clang-19
sh                                  defconfig    gcc-14
sh                    randconfig-001-20260316    gcc-12.5.0
sh                    randconfig-002-20260316    gcc-12.5.0
sh                           sh2007_defconfig    gcc-15.2.0
sparc                             allnoconfig    clang-23
sparc                               defconfig    gcc-15.2.0
sparc                 randconfig-001-20260316    gcc-12.5.0
sparc                 randconfig-002-20260316    gcc-12.5.0
sparc64                          allmodconfig    clang-23
sparc64                             defconfig    gcc-14
sparc64               randconfig-001-20260316    gcc-12.5.0
sparc64               randconfig-002-20260316    gcc-12.5.0
um                               allmodconfig    clang-19
um                                allnoconfig    clang-23
um                               allyesconfig    gcc-15.2.0
um                                  defconfig    gcc-14
um                             i386_defconfig    gcc-14
um                    randconfig-001-20260316    gcc-12.5.0
um                    randconfig-002-20260316    gcc-12.5.0
um                           x86_64_defconfig    gcc-14
x86_64                           allmodconfig    clang-20
x86_64                            allnoconfig    clang-23
x86_64                           allyesconfig    clang-20
x86_64      buildonly-randconfig-001-20260316    clang-20
x86_64      buildonly-randconfig-002-20260316    clang-20
x86_64      buildonly-randconfig-003-20260316    clang-20
x86_64      buildonly-randconfig-004-20260316    clang-20
x86_64      buildonly-randconfig-005-20260316    clang-20
x86_64      buildonly-randconfig-006-20260316    clang-20
x86_64                              defconfig    gcc-14
x86_64                                  kexec    clang-20
x86_64                randconfig-001-20260316    clang-20
x86_64                randconfig-002-20260316    clang-20
x86_64                randconfig-003-20260316    clang-20
x86_64                randconfig-004-20260316    clang-20
x86_64                randconfig-005-20260316    clang-20
x86_64                randconfig-006-20260316    clang-20
x86_64                randconfig-011-20260316    gcc-14
x86_64                randconfig-012-20260316    gcc-14
x86_64                randconfig-013-20260316    gcc-14
x86_64                randconfig-014-20260316    gcc-14
x86_64                randconfig-015-20260316    gcc-14
x86_64                randconfig-016-20260316    gcc-14
x86_64                randconfig-071-20260316    gcc-12
x86_64                randconfig-072-20260316    gcc-12
x86_64                randconfig-073-20260316    gcc-12
x86_64                randconfig-074-20260316    gcc-12
x86_64                randconfig-075-20260316    gcc-12
x86_64                randconfig-076-20260316    gcc-12
x86_64                               rhel-9.4    clang-20
x86_64                           rhel-9.4-bpf    gcc-14
x86_64                          rhel-9.4-func    clang-20
x86_64                    rhel-9.4-kselftests    clang-20
x86_64                         rhel-9.4-kunit    gcc-14
x86_64                           rhel-9.4-ltp    gcc-14
x86_64                          rhel-9.4-rust    clang-20
xtensa                            allnoconfig    clang-23
xtensa                           allyesconfig    clang-23
xtensa                randconfig-001-20260316    gcc-12.5.0
xtensa                randconfig-002-20260316    gcc-12.5.0

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* Re: [PATCH v2 1/2] dt-bindings: serial: update bindings of ultrarisc dp1000 uart
From: Krzysztof Kozlowski @ 2026-03-16  8:12 UTC (permalink / raw)
  To: Jia Wang
  Cc: Ilpo Järvinen, Andy Shevchenko, Greg Kroah-Hartman,
	Jiri Slaby, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	linux-kernel, linux-serial, linux-riscv, devicetree, Yao Zi
In-Reply-To: <20260316-ultrarisc-serial-v2-1-6ab3e7fa891c@ultrarisc.com>

On Mon, Mar 16, 2026 at 02:33:22PM +0800, Jia Wang wrote:
> Add DP1000 UART compatible information
> 

A nit, subject: drop second/last, redundant "bindings". The
"dt-bindings" prefix is already stating that these are bindings.
See also:
https://elixir.bootlin.com/linux/v6.17-rc3/source/Documentation/devicetree/bindings/submitting-patches.rst#L18

And anything can be "update". Be specific. Look at other commits how
commits and their subjects are written.

Best regards,
Krzysztof


^ permalink raw reply

* Re: [PATCH v2 1/2] dt-bindings: serial: update bindings of ultrarisc dp1000 uart
From: Krzysztof Kozlowski @ 2026-03-16  8:11 UTC (permalink / raw)
  To: Jia Wang
  Cc: Ilpo Järvinen, Andy Shevchenko, Greg Kroah-Hartman,
	Jiri Slaby, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	linux-kernel, linux-serial, linux-riscv, devicetree, Yao Zi
In-Reply-To: <20260316-ultrarisc-serial-v2-1-6ab3e7fa891c@ultrarisc.com>

On Mon, Mar 16, 2026 at 02:33:22PM +0800, Jia Wang wrote:
> Add DP1000 UART compatible information

We see this from the diff. Why this is not compatible with
snps,dw-apb-uart? What are the differences. You have entire commit msg
to explain the hardware.

> 
> Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
> Reviewed-by: Yao Zi <me@ziyao.cc>
> ---
>  Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml
> index 6efe43089a74..0040ed28e35b 100644
> --- a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml
> +++ b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml
> @@ -78,6 +78,8 @@ properties:
>                - starfive,jh7100-uart
>                - starfive,jh7110-uart
>            - const: snps,dw-apb-uart
> +      - items:

Drop, not needed.

> +          - const: ultrarisc,dp1000-uart
>        - const: snps,dw-apb-uart

So just enum with the snps one.

Best regards,
Krzysztof


^ permalink raw reply

* [PATCH v2 0/2] serial: 8250_dw: Add support for UltraRISC DP1000 uart
From: Jia Wang via B4 Relay @ 2026-03-16  6:33 UTC (permalink / raw)
  To: Ilpo Järvinen, Andy Shevchenko, Greg Kroah-Hartman,
	Jiri Slaby, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: linux-kernel, linux-serial, linux-riscv, devicetree, Jia Wang,
	Yao Zi, Zhang Xincheng

This is version 2 of the patch series.  
Previous version was sent via local SMTP, some recipients received it.  
This series is now sent via official web endpoint.

This patch series adds support for the UltraRISC DP1000 UART controller.

The series includes two patches:
1. Update device tree bindings to document the DP1000 UART compatible string
   and required properties.
2. Add driver support in the 8250_dw driver by handling the DP1000-specific
   initialization and configuration.

The patches have been tested on Ultrarisc DP1000 development board with
Linux v7.0-rc2, verifying basic UART functionality and runtime suspend/resume.

Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
---
Changes in v2:
- Rebased on Linux v7.0-rc4 (previously on v7.0-rc2).
- Reordered patch series: DT binding patch comes before driver changes.
- Updated commit message for DT binding patch.
- Link to v1: https://patch.msgid.link/20260316-ultrarisc-serial-v1-0-c464f3e933a5@ultrarisc.com

---
Jia Wang (1):
      dt-bindings: serial: update bindings of ultrarisc dp1000 uart

Zhang Xincheng (1):
      riscv: ultrarisc: 8250_dw: support DP1000 uart

 .../devicetree/bindings/serial/snps-dw-apb-uart.yaml         |  2 ++
 drivers/tty/serial/8250/8250_dw.c                            | 12 ++++++++++++
 2 files changed, 14 insertions(+)
---
base-commit: f338e77383789c0cae23ca3d48adcc5e9e137e3c
change-id: 20260309-ultrarisc-serial-64ff637edf26

Best regards,
--  
Jia Wang <wangjia@ultrarisc.com>



^ permalink raw reply

* [PATCH v2 1/2] dt-bindings: serial: update bindings of ultrarisc dp1000 uart
From: Jia Wang via B4 Relay @ 2026-03-16  6:33 UTC (permalink / raw)
  To: Ilpo Järvinen, Andy Shevchenko, Greg Kroah-Hartman,
	Jiri Slaby, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: linux-kernel, linux-serial, linux-riscv, devicetree, Jia Wang,
	Yao Zi
In-Reply-To: <20260316-ultrarisc-serial-v2-0-6ab3e7fa891c@ultrarisc.com>

From: Jia Wang <wangjia@ultrarisc.com>

Add DP1000 UART compatible information

Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
Reviewed-by: Yao Zi <me@ziyao.cc>
---
 Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml
index 6efe43089a74..0040ed28e35b 100644
--- a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml
+++ b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml
@@ -78,6 +78,8 @@ properties:
               - starfive,jh7100-uart
               - starfive,jh7110-uart
           - const: snps,dw-apb-uart
+      - items:
+          - const: ultrarisc,dp1000-uart
       - const: snps,dw-apb-uart
 
   reg:

-- 
2.34.1



^ permalink raw reply related

* [PATCH v2 2/2] riscv: ultrarisc: 8250_dw: support DP1000 uart
From: Jia Wang via B4 Relay @ 2026-03-16  6:33 UTC (permalink / raw)
  To: Ilpo Järvinen, Andy Shevchenko, Greg Kroah-Hartman,
	Jiri Slaby, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: linux-kernel, linux-serial, linux-riscv, devicetree, Jia Wang,
	Zhang Xincheng
In-Reply-To: <20260316-ultrarisc-serial-v2-0-6ab3e7fa891c@ultrarisc.com>

From: Zhang Xincheng <zhangxincheng@ultrarisc.com>

The UART of DP1000 does not support automatic detection of
buffer size. skip_autocfg needs to be set to true

Signed-off-by: Zhang Xincheng <zhangxincheng@ultrarisc.com>
Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
---
 drivers/tty/serial/8250/8250_dw.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index db73b2ae17fa..6a2acf173331 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -56,6 +56,7 @@
 #define DW_UART_QUIRK_IS_DMA_FC		BIT(3)
 #define DW_UART_QUIRK_APMC0D08		BIT(4)
 #define DW_UART_QUIRK_CPR_VALUE		BIT(5)
+#define DW_UART_QUIRK_FIXED_TYPE	BIT(6)
 
 struct dw8250_platform_data {
 	u8 usr_reg;
@@ -514,6 +515,11 @@ static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data)
 		data->data.dma.prepare_tx_dma = dw8250_prepare_tx_dma;
 		data->data.dma.prepare_rx_dma = dw8250_prepare_rx_dma;
 	}
+	if (quirks & DW_UART_QUIRK_FIXED_TYPE) {
+		p->flags |= UPF_FIXED_TYPE;
+		p->type = PORT_16550A;
+		data->skip_autocfg = true;
+	}
 	if (quirks & DW_UART_QUIRK_APMC0D08) {
 		p->iotype = UPIO_MEM32;
 		p->regshift = 2;
@@ -789,6 +795,11 @@ static const struct dw8250_platform_data dw8250_skip_set_rate_data = {
 	.quirks = DW_UART_QUIRK_SKIP_SET_RATE,
 };
 
+static const struct dw8250_platform_data dw8250_ultrarisc_dp1000_data = {
+	.usr_reg = DW_UART_USR,
+	.quirks = DW_UART_QUIRK_FIXED_TYPE,
+};
+
 static const struct of_device_id dw8250_of_match[] = {
 	{ .compatible = "snps,dw-apb-uart", .data = &dw8250_dw_apb },
 	{ .compatible = "cavium,octeon-3860-uart", .data = &dw8250_octeon_3860_data },
@@ -796,6 +807,7 @@ static const struct of_device_id dw8250_of_match[] = {
 	{ .compatible = "renesas,rzn1-uart", .data = &dw8250_renesas_rzn1_data },
 	{ .compatible = "sophgo,sg2044-uart", .data = &dw8250_skip_set_rate_data },
 	{ .compatible = "starfive,jh7100-uart", .data = &dw8250_skip_set_rate_data },
+	{ .compatible = "ultrarisc,dp1000-uart", .data = &dw8250_ultrarisc_dp1000_data },
 	{ /* Sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, dw8250_of_match);

-- 
2.34.1



^ permalink raw reply related

* Re: [PATCH 2/2] dt-bindings: serial: update bindings of ultrarisc dp1000 uart
From: Yao Zi @ 2026-03-16  4:39 UTC (permalink / raw)
  To: Jia Wang, Ilpo Järvinen, Andy Shevchenko, Greg Kroah-Hartman,
	Jiri Slaby, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: linux-kernel, linux-serial, linux-riscv, devicetree
In-Reply-To: <20260316-ultrarisc-serial-v1-2-c464f3e933a5@ultrarisc.com>

On Mon, Mar 16, 2026 at 09:36:19AM +0800, Jia Wang wrote:
> Add UltraRISC vendor-prefix information

You don't add any new vendor prefixes in this patch. This commit message
should probably be updated.

> Add DP1000 UART compatible information
> 
> Signed-off-by: Jia Wang <wangjia@ultrarisc.com>

And the dt-bindings patch should go before the driver changes.

> ---
>  Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml | 2 ++
>  1 file changed, 2 insertions(+)

Best regards,
Yao Zi

^ permalink raw reply

* [PATCH v2] MIPS: dts: loongson64g-package: Switch to Loongson UART driver
From: Rong Zhang @ 2026-03-15 18:44 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Thomas Bogendoerfer, Huacai Chen, Jiaxun Yang
  Cc: Rong Zhang, linux-kernel, linux-serial, linux-mips, devicetree,
	Yao Zi, Icenowy Zheng, Rong Zhang

Loongson64g is Loongson 3A4000, whose UART controller is compatible with
Loongson 2K1500, which is NS16550A-compatible with an additional
fractional frequency divisor register.

Update the compatible strings to reflect this, so that 3A4000 can
benefit from the fractional frequency divisor provided by loongson-uart.
This is required on some devices, otherwise their UART can't work at
some high baud rates, e.g., 115200.

Tested on Loongson-LS3A4000-7A1000-NUC-SE with a 25MHz UART clock.
Without fractional frequency divisor, the actual baud rate was 111607
(25MHz / 16 / 14, measured value: 111545) and some USB-to-UART
converters couldn't work with it at all. With fractional frequency
divisor, the measured baud rate becomes 115207, which is quite accurate.

Signed-off-by: Rong Zhang <rongrong@oss.cipunited.com>
---
This patch targets the MIPS tree.

The series for the serial tree to update dt-bindings and enable building
8250_loongson (loongson-uart) on MIPS Loongson64 is sent separately, as
it's independant of this patch and can be applied in any order (the
compatible strings here still contain "ns16550a", so no regression will
be introduced).

Changes in v2:
- Separated from v1 (patch 3): https://lore.kernel.org/r/20260314234143.651298-1-rongrong@oss.cipunited.com/
(thanks Krzysztof Kozlowski)
---
 arch/mips/boot/dts/loongson/loongson64g-package.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/mips/boot/dts/loongson/loongson64g-package.dtsi b/arch/mips/boot/dts/loongson/loongson64g-package.dtsi
index d4314f62ccc2..029daeedd0ab 100644
--- a/arch/mips/boot/dts/loongson/loongson64g-package.dtsi
+++ b/arch/mips/boot/dts/loongson/loongson64g-package.dtsi
@@ -40,7 +40,7 @@ liointc: interrupt-controller@3ff01400 {
 		};
 
 		cpu_uart0: serial@1fe00100 {
-			compatible = "ns16550a";
+			compatible = "loongson,ls3a4000-uart", "loongson,ls2k1500-uart", "ns16550a";
 			reg = <0 0x1fe00100 0x10>;
 			clock-frequency = <100000000>;
 			interrupt-parent = <&liointc>;
@@ -50,7 +50,7 @@ cpu_uart0: serial@1fe00100 {
 
 		cpu_uart1: serial@1fe00110 {
 			status = "disabled";
-			compatible = "ns16550a";
+			compatible = "loongson,ls3a4000-uart", "loongson,ls2k1500-uart", "ns16550a";
 			reg = <0 0x1fe00110 0x10>;
 			clock-frequency = <100000000>;
 			interrupts = <15 IRQ_TYPE_LEVEL_HIGH>;

base-commit: 267594792a71018788af69e836c52e34bb8054af
-- 
2.53.0

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox