Devicetree
 help / color / mirror / Atom feed
* [PATCH v3 0/2] pinctrl: ultrarisc: add DP1000 pinctrl support
@ 2026-06-08  7:50 Jia Wang via B4 Relay
  2026-06-08  7:50 ` [PATCH v3 1/2] dt-bindings: pinctrl: Add UltraRISC DP1000 pinctrl controller Jia Wang via B4 Relay
  2026-06-08  7:50 ` [PATCH v3 2/2] pinctrl: ultrarisc: Add UltraRISC DP1000 pinctrl driver Jia Wang via B4 Relay
  0 siblings, 2 replies; 4+ messages in thread
From: Jia Wang via B4 Relay @ 2026-06-08  7:50 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bartosz Golaszewski
  Cc: linux-gpio, devicetree, linux-kernel, Jia Wang

This series adds the devicetree schema and the pinctrl driver for the
DP1000 controller using generic pinctrl bindings.

Compared with v1, this series is narrowed down to the pinctrl binding
and driver only. v1 patches 1, 2, 3, 5, 7, 8, and 9 (vendor prefix,
CPU/SoC bindings, DTS files, and defconfig update) are not included in
v2 and will be sent separately.

Note:
- ARCH_ULTRARISC support is being reviewed separately:
  * Link: https://lore.kernel.org/lkml/20260427-ultrarisc-pcie-v4-1-98935f6cdfb5@ultrarisc.com/

Testing:
- dt_binding_check and yamllint
- Kernel build for RISC-V and boot-tested on DP1000 (Milk-V Titan and
  Rongda M0)

Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
---
Changes in v3:
- Re-add the DT binding header and use numeric pin IDs in the binding.
- Replace instance-specific mux names with generic function names.
- Tighten the schema constraints for A-D and LPC pins.
- Switch the driver to pinctrl_generic_pins_function_dt_node_to_map()
  and resolve mux routes from the pins + function combination.
- Link to v2: https://patch.msgid.link/20260601-ultrarisc-pinctrl-v2-0-07ac5130a96d@ultrarisc.com

Changes in v2:
- Split the vendor prefix, CPU binding, SoC binding, DTS, and defconfig
  patches out of this series for separate submission.
- Drop the legacy DT node format from both the binding and the driver,
  and switch to the generic pinctrl interface with
  pinconf_generic_dt_node_to_map_all().
- Drop the DT binding header from the series.
- Replace the generic func0/func1 mux names with named hardware functions
  in the binding and driver.
- Wire the driver through CONFIG_PINCTRL_ULTRARISC and add COMPILE_TEST
  coverage.
- Restrict function selection to valid pins in the driver.
- Link to v1: https://patch.msgid.link/20260515-ultrarisc-pinctrl-v1-0-bf559589ea8a@ultrarisc.com

---
Jia Wang (2):
      dt-bindings: pinctrl: Add UltraRISC DP1000 pinctrl controller
      pinctrl: ultrarisc: Add UltraRISC DP1000 pinctrl driver

 .../bindings/pinctrl/ultrarisc,dp1000-pinctrl.yaml | 131 ++++++
 MAINTAINERS                                        |   7 +
 drivers/pinctrl/Kconfig                            |   1 +
 drivers/pinctrl/Makefile                           |   1 +
 drivers/pinctrl/ultrarisc/Kconfig                  |  21 +
 drivers/pinctrl/ultrarisc/Makefile                 |   4 +
 drivers/pinctrl/ultrarisc/pinctrl-dp1000.c         | 168 +++++++
 drivers/pinctrl/ultrarisc/pinctrl-ultrarisc.c      | 503 +++++++++++++++++++++
 drivers/pinctrl/ultrarisc/pinctrl-ultrarisc.h      |  63 +++
 .../dt-bindings/pinctrl/ultrarisc,dp1000-pinctrl.h |  63 +++
 10 files changed, 962 insertions(+)
---
base-commit: 8e65320d91cdc3b241d4b94855c88459b91abf66
change-id: 20260316-ultrarisc-pinctrl-efa6e24c4803

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



^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v3 1/2] dt-bindings: pinctrl: Add UltraRISC DP1000 pinctrl controller
  2026-06-08  7:50 [PATCH v3 0/2] pinctrl: ultrarisc: add DP1000 pinctrl support Jia Wang via B4 Relay
@ 2026-06-08  7:50 ` Jia Wang via B4 Relay
  2026-06-08  7:57   ` sashiko-bot
  2026-06-08  7:50 ` [PATCH v3 2/2] pinctrl: ultrarisc: Add UltraRISC DP1000 pinctrl driver Jia Wang via B4 Relay
  1 sibling, 1 reply; 4+ messages in thread
From: Jia Wang via B4 Relay @ 2026-06-08  7:50 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bartosz Golaszewski
  Cc: linux-gpio, devicetree, linux-kernel, Jia Wang

From: Jia Wang <wangjia@ultrarisc.com>

Add doc for the pinctrl controllers on the UltraRISC DP1000 RISC-V SoC.

Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
---
 .../bindings/pinctrl/ultrarisc,dp1000-pinctrl.yaml | 131 +++++++++++++++++++++
 MAINTAINERS                                        |   6 +
 .../dt-bindings/pinctrl/ultrarisc,dp1000-pinctrl.h |  63 ++++++++++
 3 files changed, 200 insertions(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/ultrarisc,dp1000-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/ultrarisc,dp1000-pinctrl.yaml
new file mode 100644
index 000000000000..a64fbfc616db
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/ultrarisc,dp1000-pinctrl.yaml
@@ -0,0 +1,131 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/ultrarisc,dp1000-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: UltraRISC DP1000 Pin Controller
+
+maintainers:
+  - Jia Wang <wangjia@ultrarisc.com>
+
+description: |
+  UltraRISC RISC-V SoC DP1000 pin controller.
+  The controller manages ports A, B, C, D and LPC. Ports A-D default to
+  GPIO and provide additional SPI, UART, I2C, and PWM mux functions.
+  LPC pins default to the LPC interface and can be muxed to eSPI.
+  All pins also support pin configuration, including drive strength,
+  pull-up, and pull-down settings.
+
+properties:
+  compatible:
+    const: ultrarisc,dp1000-pinctrl
+
+  reg:
+    items:
+      - description: pin controller registers
+
+required:
+  - compatible
+  - reg
+
+patternProperties:
+  '.*-pins$':
+    type: object
+    unevaluatedProperties: false
+    allOf:
+      - $ref: /schemas/pinctrl/pincfg-node.yaml#
+      - $ref: /schemas/pinctrl/pinmux-node.yaml#
+      - if:
+          properties:
+            pins:
+              items:
+                minimum: 40
+                maximum: 52
+        then:
+          properties:
+            function:
+              enum:
+                - lpc
+                - espi
+        else:
+          properties:
+            pins:
+              items:
+                maximum: 39
+            function:
+              enum:
+                - gpio
+                - i2c
+                - pwm
+                - spi
+                - uart
+
+    properties:
+      pins:
+        description: |
+          List of pins affected by this state node, using the numeric pin IDs
+          defined in dt-bindings/pinctrl/ultrarisc,dp1000-pinctrl.h.
+        $ref: /schemas/types.yaml#/definitions/uint32-array
+        minItems: 1
+        uniqueItems: true
+        items:
+          minimum: 0
+          maximum: 52
+
+      function:
+        description: |
+          Mux function to select for the listed pins. Supported functions
+          depend on the selected pins and match the DP1000 hardware mux
+          table.
+        enum:
+          - gpio
+          - i2c
+          - pwm
+          - spi
+          - uart
+          - lpc
+          - espi
+
+      bias-disable: true
+      bias-high-impedance: true
+      bias-pull-up: true
+      bias-pull-down: true
+
+      drive-strength:
+        description: Output drive strength in mA.
+        enum: [20, 27, 33, 40]
+
+    required:
+      - pins
+      - function
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/pinctrl/ultrarisc,dp1000-pinctrl.h>
+
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      pinctrl@11081000 {
+        compatible = "ultrarisc,dp1000-pinctrl";
+        reg = <0x0 0x11081000 0x0 0x1000>;
+
+        i2c0-pins {
+          pins = <PA12 PA13>;
+          function = "i2c";
+          bias-pull-up;
+          drive-strength = <33>;
+        };
+
+        uart0-pins {
+          pins = <PA8 PA9>;
+          function = "uart";
+          bias-pull-up;
+          drive-strength = <33>;
+        };
+      };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index e035a3be797c..1ef874d342a5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -27357,6 +27357,12 @@ S:	Maintained
 F:	drivers/usb/common/ulpi.c
 F:	include/linux/ulpi/
 
+ULTRARISC DP1000 PINCTRL DRIVER
+M:	Jia Wang <wangjia@ultrarisc.com>
+L:	linux-gpio@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/pinctrl/ultrarisc,dp1000-pinctrl.yaml
+
 ULTRATRONIK BOARD SUPPORT
 M:	Goran Rađenović <goran.radni@gmail.com>
 M:	Börge Strümpfel <boerge.struempfel@gmail.com>
diff --git a/include/dt-bindings/pinctrl/ultrarisc,dp1000-pinctrl.h b/include/dt-bindings/pinctrl/ultrarisc,dp1000-pinctrl.h
new file mode 100644
index 000000000000..f800c9722471
--- /dev/null
+++ b/include/dt-bindings/pinctrl/ultrarisc,dp1000-pinctrl.h
@@ -0,0 +1,63 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2026 UltraRISC Technology (Shanghai) Co., Ltd.
+ */
+
+#ifndef _DT_BINDINGS_PINCTRL_ULTRARISC_DP1000_H
+#define _DT_BINDINGS_PINCTRL_ULTRARISC_DP1000_H
+
+#define PA0		0
+#define PA1		1
+#define PA2		2
+#define PA3		3
+#define PA4		4
+#define PA5		5
+#define PA6		6
+#define PA7		7
+#define PA8		8
+#define PA9		9
+#define PA10		10
+#define PA11		11
+#define PA12		12
+#define PA13		13
+#define PA14		14
+#define PA15		15
+#define PB0		16
+#define PB1		17
+#define PB2		18
+#define PB3		19
+#define PB4		20
+#define PB5		21
+#define PB6		22
+#define PB7		23
+#define PC0		24
+#define PC1		25
+#define PC2		26
+#define PC3		27
+#define PC4		28
+#define PC5		29
+#define PC6		30
+#define PC7		31
+#define PD0		32
+#define PD1		33
+#define PD2		34
+#define PD3		35
+#define PD4		36
+#define PD5		37
+#define PD6		38
+#define PD7		39
+#define LPC0		40
+#define LPC1		41
+#define LPC2		42
+#define LPC3		43
+#define LPC4		44
+#define LPC5		45
+#define LPC6		46
+#define LPC7		47
+#define LPC8		48
+#define LPC9		49
+#define LPC10		50
+#define LPC11		51
+#define LPC12		52
+
+#endif /* _DT_BINDINGS_PINCTRL_ULTRARISC_DP1000_H */

-- 
2.34.1



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v3 2/2] pinctrl: ultrarisc: Add UltraRISC DP1000 pinctrl driver
  2026-06-08  7:50 [PATCH v3 0/2] pinctrl: ultrarisc: add DP1000 pinctrl support Jia Wang via B4 Relay
  2026-06-08  7:50 ` [PATCH v3 1/2] dt-bindings: pinctrl: Add UltraRISC DP1000 pinctrl controller Jia Wang via B4 Relay
@ 2026-06-08  7:50 ` Jia Wang via B4 Relay
  1 sibling, 0 replies; 4+ messages in thread
From: Jia Wang via B4 Relay @ 2026-06-08  7:50 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bartosz Golaszewski
  Cc: linux-gpio, devicetree, linux-kernel, Jia Wang

From: Jia Wang <wangjia@ultrarisc.com>

Add support for the pin controller on the UltraRISC DP1000 SoC.

The controller provides mux selection for pins in ports A, B, C, D, and
LPC. Ports A-D default to GPIO and support peripheral muxing. LPC pins
can be switched to eSPI, but are not available as GPIOs. Basic pin
configuration controls such as drive strength, pull-up, and pull-down
are also supported.

Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
---
 MAINTAINERS                                   |   1 +
 drivers/pinctrl/Kconfig                       |   1 +
 drivers/pinctrl/Makefile                      |   1 +
 drivers/pinctrl/ultrarisc/Kconfig             |  21 ++
 drivers/pinctrl/ultrarisc/Makefile            |   4 +
 drivers/pinctrl/ultrarisc/pinctrl-dp1000.c    | 168 +++++++++
 drivers/pinctrl/ultrarisc/pinctrl-ultrarisc.c | 503 ++++++++++++++++++++++++++
 drivers/pinctrl/ultrarisc/pinctrl-ultrarisc.h |  63 ++++
 8 files changed, 762 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 1ef874d342a5..04f2126d8af5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -27362,6 +27362,7 @@ M:	Jia Wang <wangjia@ultrarisc.com>
 L:	linux-gpio@vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/pinctrl/ultrarisc,dp1000-pinctrl.yaml
+F:	drivers/pinctrl/ultrarisc/*
 
 ULTRATRONIK BOARD SUPPORT
 M:	Goran Rađenović <goran.radni@gmail.com>
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 03f2e3ee065f..2a5491e3fb47 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -708,6 +708,7 @@ source "drivers/pinctrl/sunplus/Kconfig"
 source "drivers/pinctrl/sunxi/Kconfig"
 source "drivers/pinctrl/tegra/Kconfig"
 source "drivers/pinctrl/ti/Kconfig"
+source "drivers/pinctrl/ultrarisc/Kconfig"
 source "drivers/pinctrl/uniphier/Kconfig"
 source "drivers/pinctrl/visconti/Kconfig"
 source "drivers/pinctrl/vt8500/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index f7d5d5f76d0c..61d502ba06b9 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -95,6 +95,7 @@ obj-y				+= sunplus/
 obj-$(CONFIG_PINCTRL_SUNXI)	+= sunxi/
 obj-$(CONFIG_ARCH_TEGRA)	+= tegra/
 obj-y				+= ti/
+obj-$(CONFIG_PINCTRL_ULTRARISC)	+= ultrarisc/
 obj-$(CONFIG_PINCTRL_UNIPHIER)	+= uniphier/
 obj-$(CONFIG_PINCTRL_VISCONTI)	+= visconti/
 obj-$(CONFIG_ARCH_VT8500)	+= vt8500/
diff --git a/drivers/pinctrl/ultrarisc/Kconfig b/drivers/pinctrl/ultrarisc/Kconfig
new file mode 100644
index 000000000000..d81a152f2f4b
--- /dev/null
+++ b/drivers/pinctrl/ultrarisc/Kconfig
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config PINCTRL_ULTRARISC
+	tristate
+	depends on OF
+	depends on ARCH_ULTRARISC || COMPILE_TEST
+	select GENERIC_PINCTRL
+	select PINMUX
+	select GPIOLIB
+
+config PINCTRL_ULTRARISC_DP1000
+	tristate "UltraRISC DP1000 SoC Pinctrl driver"
+	select PINCTRL_ULTRARISC
+	depends on OF && HAS_IOMEM
+	depends on ARCH_ULTRARISC || COMPILE_TEST
+	default ARCH_ULTRARISC
+	help
+	  Say Y to select the pinctrl driver for UltraRISC DP1000 SoC.
+	  This pin controller allows selecting the mux function for
+	  each pin. This driver can also be built as a module called
+	  pinctrl-dp1000.
diff --git a/drivers/pinctrl/ultrarisc/Makefile b/drivers/pinctrl/ultrarisc/Makefile
new file mode 100644
index 000000000000..5d49ce1c0af9
--- /dev/null
+++ b/drivers/pinctrl/ultrarisc/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_PINCTRL_ULTRARISC)		+= pinctrl-ultrarisc.o
+obj-$(CONFIG_PINCTRL_ULTRARISC_DP1000)	+= pinctrl-dp1000.o
diff --git a/drivers/pinctrl/ultrarisc/pinctrl-dp1000.c b/drivers/pinctrl/ultrarisc/pinctrl-dp1000.c
new file mode 100644
index 000000000000..f9c85c8c4433
--- /dev/null
+++ b/drivers/pinctrl/ultrarisc/pinctrl-dp1000.c
@@ -0,0 +1,168 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2026 UltraRISC Technology (Shanghai) Co., Ltd.
+ *
+ * Author: Jia Wang <wangjia@ultrarisc.com>
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include "pinctrl-ultrarisc.h"
+
+/* Port indices. */
+#define UR_DP1000_PORT_A_IDX		0
+#define UR_DP1000_PORT_B_IDX		1
+#define UR_DP1000_PORT_C_IDX		2
+#define UR_DP1000_PORT_D_IDX		3
+#define UR_DP1000_PORT_LPC_IDX		4
+
+/* Port mux register offsets. */
+#define UR_DP1000_PORTA_FUNC_OFFSET	0x2c0
+#define UR_DP1000_PORTB_FUNC_OFFSET	0x2c4
+#define UR_DP1000_PORTC_FUNC_OFFSET	0x2c8
+#define UR_DP1000_PORTD_FUNC_OFFSET	0x2cc
+#define UR_DP1000_PORTLPC_FUNC_OFFSET	0x2d0
+
+/* Port pinconf register offsets. */
+#define UR_DP1000_PORTA_CONF_OFFSET	0x310
+#define UR_DP1000_PORTB_CONF_OFFSET	0x318
+#define UR_DP1000_PORTC_CONF_OFFSET	0x31c
+#define UR_DP1000_PORTD_CONF_OFFSET	0x320
+#define UR_DP1000_PORTLPC_CONF_OFFSET	0x324
+
+/* Pin ranges for function descriptors. */
+#define UR_DP1000_PINS_ABCD	GENMASK_ULL(39, 0)
+#define UR_DP1000_PINS_LPC	GENMASK_ULL(52, 40)
+
+/* Static table entry helpers. */
+#define UR_DP1000_PORT(_base, _npins, _func, _conf, _modes, _gpio) \
+	{ .pin_base = (_base), .npins = (_npins), .func_offset = (_func), \
+	  .conf_offset = (_conf), .supported_modes = (_modes), \
+	  .supports_gpio = (_gpio) }
+
+#define UR_DP1000_PIN(_nr, _name, _port) \
+	{ .number = (_nr), .name = (_name), .drv_data = (void *)&ur_dp1000_ports[_port] }
+
+static const struct ur_func_route ur_dp1000_routes[] = {
+	{ "gpio", UR_FUNC_DEFAULT, UR_DP1000_PINS_ABCD },
+	{ "i2c", UR_FUNC_0, GENMASK_ULL(13, 12) },
+	{ "i2c", UR_FUNC_0, GENMASK_ULL(23, 22) },
+	{ "i2c", UR_FUNC_0, GENMASK_ULL(25, 24) },
+	{ "i2c", UR_FUNC_0, GENMASK_ULL(27, 26) },
+	{ "pwm", UR_FUNC_0, GENMASK_ULL(19, 16) },
+	{ "spi", UR_FUNC_1, GENMASK_ULL(39, 32) },
+	{ "spi", UR_FUNC_0, GENMASK_ULL(6, 0) },
+	{ "uart", UR_FUNC_1, GENMASK_ULL(9, 8) },
+	{ "uart", UR_FUNC_0, GENMASK_ULL(21, 20) },
+	{ "uart", UR_FUNC_0, GENMASK_ULL(29, 28) },
+	{ "uart", UR_FUNC_0, GENMASK_ULL(31, 30) },
+	{ "lpc", UR_FUNC_DEFAULT, UR_DP1000_PINS_LPC },
+	{ "espi", UR_FUNC_0, UR_DP1000_PINS_LPC },
+};
+
+static const struct ur_port_desc ur_dp1000_ports[] = {
+	UR_DP1000_PORT(0, 16, UR_DP1000_PORTA_FUNC_OFFSET,
+		       UR_DP1000_PORTA_CONF_OFFSET,
+		       UR_FUNC_0 | UR_FUNC_1, true),
+	UR_DP1000_PORT(16, 8, UR_DP1000_PORTB_FUNC_OFFSET,
+		       UR_DP1000_PORTB_CONF_OFFSET,
+		       UR_FUNC_0 | UR_FUNC_1, true),
+	UR_DP1000_PORT(24, 8, UR_DP1000_PORTC_FUNC_OFFSET,
+		       UR_DP1000_PORTC_CONF_OFFSET,
+		       UR_FUNC_0 | UR_FUNC_1, true),
+	UR_DP1000_PORT(32, 8, UR_DP1000_PORTD_FUNC_OFFSET,
+		       UR_DP1000_PORTD_CONF_OFFSET,
+		       UR_FUNC_0 | UR_FUNC_1, true),
+	UR_DP1000_PORT(40, 13, UR_DP1000_PORTLPC_FUNC_OFFSET,
+		       UR_DP1000_PORTLPC_CONF_OFFSET,
+		       UR_FUNC_0,             false),
+};
+
+static const struct pinctrl_pin_desc ur_dp1000_pins[] = {
+	UR_DP1000_PIN(0, "PA0", UR_DP1000_PORT_A_IDX),
+	UR_DP1000_PIN(1, "PA1", UR_DP1000_PORT_A_IDX),
+	UR_DP1000_PIN(2, "PA2", UR_DP1000_PORT_A_IDX),
+	UR_DP1000_PIN(3, "PA3", UR_DP1000_PORT_A_IDX),
+	UR_DP1000_PIN(4, "PA4", UR_DP1000_PORT_A_IDX),
+	UR_DP1000_PIN(5, "PA5", UR_DP1000_PORT_A_IDX),
+	UR_DP1000_PIN(6, "PA6", UR_DP1000_PORT_A_IDX),
+	UR_DP1000_PIN(7, "PA7", UR_DP1000_PORT_A_IDX),
+	UR_DP1000_PIN(8, "PA8", UR_DP1000_PORT_A_IDX),
+	UR_DP1000_PIN(9, "PA9", UR_DP1000_PORT_A_IDX),
+	UR_DP1000_PIN(10, "PA10", UR_DP1000_PORT_A_IDX),
+	UR_DP1000_PIN(11, "PA11", UR_DP1000_PORT_A_IDX),
+	UR_DP1000_PIN(12, "PA12", UR_DP1000_PORT_A_IDX),
+	UR_DP1000_PIN(13, "PA13", UR_DP1000_PORT_A_IDX),
+	UR_DP1000_PIN(14, "PA14", UR_DP1000_PORT_A_IDX),
+	UR_DP1000_PIN(15, "PA15", UR_DP1000_PORT_A_IDX),
+	UR_DP1000_PIN(16, "PB0", UR_DP1000_PORT_B_IDX),
+	UR_DP1000_PIN(17, "PB1", UR_DP1000_PORT_B_IDX),
+	UR_DP1000_PIN(18, "PB2", UR_DP1000_PORT_B_IDX),
+	UR_DP1000_PIN(19, "PB3", UR_DP1000_PORT_B_IDX),
+	UR_DP1000_PIN(20, "PB4", UR_DP1000_PORT_B_IDX),
+	UR_DP1000_PIN(21, "PB5", UR_DP1000_PORT_B_IDX),
+	UR_DP1000_PIN(22, "PB6", UR_DP1000_PORT_B_IDX),
+	UR_DP1000_PIN(23, "PB7", UR_DP1000_PORT_B_IDX),
+	UR_DP1000_PIN(24, "PC0", UR_DP1000_PORT_C_IDX),
+	UR_DP1000_PIN(25, "PC1", UR_DP1000_PORT_C_IDX),
+	UR_DP1000_PIN(26, "PC2", UR_DP1000_PORT_C_IDX),
+	UR_DP1000_PIN(27, "PC3", UR_DP1000_PORT_C_IDX),
+	UR_DP1000_PIN(28, "PC4", UR_DP1000_PORT_C_IDX),
+	UR_DP1000_PIN(29, "PC5", UR_DP1000_PORT_C_IDX),
+	UR_DP1000_PIN(30, "PC6", UR_DP1000_PORT_C_IDX),
+	UR_DP1000_PIN(31, "PC7", UR_DP1000_PORT_C_IDX),
+	UR_DP1000_PIN(32, "PD0", UR_DP1000_PORT_D_IDX),
+	UR_DP1000_PIN(33, "PD1", UR_DP1000_PORT_D_IDX),
+	UR_DP1000_PIN(34, "PD2", UR_DP1000_PORT_D_IDX),
+	UR_DP1000_PIN(35, "PD3", UR_DP1000_PORT_D_IDX),
+	UR_DP1000_PIN(36, "PD4", UR_DP1000_PORT_D_IDX),
+	UR_DP1000_PIN(37, "PD5", UR_DP1000_PORT_D_IDX),
+	UR_DP1000_PIN(38, "PD6", UR_DP1000_PORT_D_IDX),
+	UR_DP1000_PIN(39, "PD7", UR_DP1000_PORT_D_IDX),
+	UR_DP1000_PIN(40, "LPC0", UR_DP1000_PORT_LPC_IDX),
+	UR_DP1000_PIN(41, "LPC1", UR_DP1000_PORT_LPC_IDX),
+	UR_DP1000_PIN(42, "LPC2", UR_DP1000_PORT_LPC_IDX),
+	UR_DP1000_PIN(43, "LPC3", UR_DP1000_PORT_LPC_IDX),
+	UR_DP1000_PIN(44, "LPC4", UR_DP1000_PORT_LPC_IDX),
+	UR_DP1000_PIN(45, "LPC5", UR_DP1000_PORT_LPC_IDX),
+	UR_DP1000_PIN(46, "LPC6", UR_DP1000_PORT_LPC_IDX),
+	UR_DP1000_PIN(47, "LPC7", UR_DP1000_PORT_LPC_IDX),
+	UR_DP1000_PIN(48, "LPC8", UR_DP1000_PORT_LPC_IDX),
+	UR_DP1000_PIN(49, "LPC9", UR_DP1000_PORT_LPC_IDX),
+	UR_DP1000_PIN(50, "LPC10", UR_DP1000_PORT_LPC_IDX),
+	UR_DP1000_PIN(51, "LPC11", UR_DP1000_PORT_LPC_IDX),
+	UR_DP1000_PIN(52, "LPC12", UR_DP1000_PORT_LPC_IDX),
+};
+
+static const struct ur_pinctrl_data ur_dp1000_pinctrl_data = {
+	.pins = ur_dp1000_pins,
+	.npins = ARRAY_SIZE(ur_dp1000_pins),
+	.routes = ur_dp1000_routes,
+	.num_routes = ARRAY_SIZE(ur_dp1000_routes),
+};
+
+static const struct of_device_id ur_pinctrl_of_match[] = {
+	{ .compatible = "ultrarisc,dp1000-pinctrl" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, ur_pinctrl_of_match);
+
+static int ur_dp1000_pinctrl_probe(struct platform_device *pdev)
+{
+	return ur_pinctrl_probe(pdev, &ur_dp1000_pinctrl_data);
+}
+
+static struct platform_driver ur_pinctrl_driver = {
+	.driver = {
+		.name = "ultrarisc-pinctrl-dp1000",
+		.of_match_table = ur_pinctrl_of_match,
+	},
+	.probe = ur_dp1000_pinctrl_probe,
+};
+
+module_platform_driver(ur_pinctrl_driver);
+
+MODULE_DESCRIPTION("UltraRISC DP1000 pinctrl driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/ultrarisc/pinctrl-ultrarisc.c b/drivers/pinctrl/ultrarisc/pinctrl-ultrarisc.c
new file mode 100644
index 000000000000..5c123873f50e
--- /dev/null
+++ b/drivers/pinctrl/ultrarisc/pinctrl-ultrarisc.c
@@ -0,0 +1,503 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2026 UltraRISC Technology (Shanghai) Co., Ltd.
+ *
+ * Author: Jia Wang <wangjia@ultrarisc.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+
+#include "../core.h"
+#include "../devicetree.h"
+#include "../pinconf.h"
+#include "../pinmux.h"
+
+#include "pinctrl-ultrarisc.h"
+
+#define UR_CONF_BIT_PER_PIN	4
+#define UR_CONF_PIN_PER_REG	(32 / UR_CONF_BIT_PER_PIN)
+static const u32 ur_drive_strengths[] = { 20, 27, 33, 40 };
+
+static const struct ur_port_desc *ur_get_pin_port(struct pinctrl_dev *pctldev,
+						  unsigned int pin)
+{
+	const struct pin_desc *desc = pin_desc_get(pctldev, pin);
+
+	if (!desc || !desc->drv_data)
+		return NULL;
+
+	return desc->drv_data;
+}
+
+static u32 ur_get_pin_conf_offset(const struct ur_port_desc *port_desc, u32 pin)
+{
+	return port_desc->conf_offset +
+	       (pin / UR_CONF_PIN_PER_REG) * sizeof(u32);
+}
+
+static int ur_read_pin_conf(struct ur_pinctrl *pctrl, unsigned int pin, u32 *conf)
+{
+	const struct ur_port_desc *port_desc;
+	u32 pin_offset;
+	u32 reg_offset;
+	u32 shift;
+	u32 mask;
+
+	port_desc = ur_get_pin_port(pctrl->pctl_dev, pin);
+	if (!port_desc)
+		return -EINVAL;
+
+	pin_offset = pin - port_desc->pin_base;
+	reg_offset = ur_get_pin_conf_offset(port_desc, pin_offset);
+	shift = (pin_offset % UR_CONF_PIN_PER_REG) * UR_CONF_BIT_PER_PIN;
+	mask = GENMASK(UR_CONF_BIT_PER_PIN - 1, 0) << shift;
+	*conf = field_get(mask, readl_relaxed(pctrl->base + reg_offset));
+
+	return 0;
+}
+
+static int ur_write_pin_conf(struct ur_pinctrl *pctrl, unsigned int pin, u32 conf)
+{
+	const struct ur_port_desc *port_desc;
+	unsigned long flags;
+	void __iomem *reg;
+	u32 pin_offset;
+	u32 reg_offset;
+	u32 shift;
+	u32 mask;
+	u32 val;
+
+	port_desc = ur_get_pin_port(pctrl->pctl_dev, pin);
+	if (!port_desc)
+		return -EINVAL;
+
+	pin_offset = pin - port_desc->pin_base;
+	reg_offset = ur_get_pin_conf_offset(port_desc, pin_offset);
+	reg = pctrl->base + reg_offset;
+	shift = (pin_offset % UR_CONF_PIN_PER_REG) * UR_CONF_BIT_PER_PIN;
+	mask = GENMASK(UR_CONF_BIT_PER_PIN - 1, 0) << shift;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	val = readl_relaxed(reg);
+	val = (val & ~mask) | field_prep(mask, conf);
+	writel_relaxed(val, reg);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return 0;
+}
+
+static int ur_set_pin_mux(struct ur_pinctrl *pctrl,
+			  const struct ur_port_desc *port_desc,
+			  u32 pin_offset, u32 mode)
+{
+	void __iomem *reg = pctrl->base + port_desc->func_offset;
+	unsigned long flags;
+	u32 val;
+
+	if (WARN_ON(pin_offset >= UR_MAX_PINS_PER_PORT))
+		return -EINVAL;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	val = readl_relaxed(reg);
+	val &= ~((UR_FUNC_0 | UR_FUNC_1) << pin_offset);
+	val |= mode << pin_offset;
+	writel_relaxed(val, reg);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return 0;
+}
+
+static int ur_set_pin_mux_by_num(struct ur_pinctrl *pctrl, unsigned int pin, u32 mode)
+{
+	const struct ur_port_desc *port_desc = ur_get_pin_port(pctrl->pctl_dev, pin);
+	u32 pin_offset;
+
+	if (!port_desc)
+		return -EINVAL;
+
+	if (mode != UR_FUNC_DEFAULT && !(port_desc->supported_modes & mode))
+		return -EINVAL;
+
+	pin_offset = pin - port_desc->pin_base;
+
+	return ur_set_pin_mux(pctrl, port_desc, pin_offset, mode);
+}
+
+static int ur_hw_to_config(unsigned long *config, u32 conf)
+{
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	u32 drive = FIELD_GET(UR_DRIVE_MASK, conf);
+	u32 pull = FIELD_GET(UR_PULL_MASK, conf);
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_DISABLE:
+	case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
+		if (pull != UR_PULL_DIS)
+			return -EINVAL;
+		*config = pinconf_to_config_packed(param, 1);
+		return 0;
+	case PIN_CONFIG_BIAS_PULL_UP:
+		if (pull != UR_PULL_UP)
+			return -EINVAL;
+		*config = pinconf_to_config_packed(param, 1);
+		return 0;
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+	case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
+		if (pull != UR_PULL_DOWN)
+			return -EINVAL;
+		*config = pinconf_to_config_packed(param, 1);
+		return 0;
+	case PIN_CONFIG_DRIVE_STRENGTH:
+		if (drive >= ARRAY_SIZE(ur_drive_strengths))
+			return -EINVAL;
+		*config = pinconf_to_config_packed(param, ur_drive_strengths[drive]);
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int ur_config_to_hw(unsigned long config, u32 *conf)
+{
+	enum pin_config_param param = pinconf_to_config_param(config);
+	u32 arg = pinconf_to_config_argument(config);
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_DISABLE:
+	case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
+		FIELD_MODIFY(UR_PULL_MASK, conf, UR_PULL_DIS);
+		return 0;
+	case PIN_CONFIG_BIAS_PULL_UP:
+		FIELD_MODIFY(UR_PULL_MASK, conf, UR_PULL_UP);
+		return 0;
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+	case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
+		FIELD_MODIFY(UR_PULL_MASK, conf, UR_PULL_DOWN);
+		return 0;
+	case PIN_CONFIG_DRIVE_STRENGTH:
+		for (u32 i = 0; i < ARRAY_SIZE(ur_drive_strengths); i++) {
+			if (ur_drive_strengths[i] != arg)
+				continue;
+			FIELD_MODIFY(UR_DRIVE_MASK, conf, i);
+			return 0;
+		}
+		return -EINVAL;
+	case PIN_CONFIG_PERSIST_STATE:
+		/*
+		 * For PIN_CONFIG_PERSIST_STATE, gpiolib only treats
+		 * -ENOTSUPP as an optional unsupported result.
+		 * Do not use -EOPNOTSUPP here.
+		 */
+		return -ENOTSUPP;
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int ur_find_group_route(struct ur_pinctrl *pctrl,
+			       const char *function,
+			       u64 group_mask,
+			       const struct ur_func_route **route_out)
+{
+	const struct ur_func_route *match = NULL;
+
+	for (u32 i = 0; i < pctrl->data->num_routes; i++) {
+		const struct ur_func_route *route = &pctrl->data->routes[i];
+
+		if (strcmp(route->function, function))
+			continue;
+
+		if ((route->valid_pins & group_mask) != group_mask)
+			continue;
+
+		if (match) {
+			dev_err(pctrl->dev,
+				"ambiguous route for function %s group_mask=%#llx\n",
+				function, (unsigned long long)group_mask);
+			return -EINVAL;
+		}
+
+		match = route;
+	}
+
+	if (match) {
+		*route_out = match;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static const char *ur_get_group_function(struct pinctrl_dev *pctldev,
+					 unsigned int group_selector,
+					 unsigned int pin_index)
+{
+	const struct group_desc *group;
+	const char * const *functions;
+
+	group = pinctrl_generic_get_group(pctldev, group_selector);
+	if (!group || pin_index >= group->grp.npins || !group->data)
+		return NULL;
+
+	functions = group->data;
+
+	return functions[pin_index];
+}
+
+static int ur_resolve_group_mux(struct pinctrl_dev *pctldev,
+				struct ur_pinctrl *pctrl,
+				unsigned int group_selector,
+				const unsigned int *pins,
+				unsigned int npins,
+				const struct ur_func_route **route_out)
+{
+	const char *function;
+	u64 group_mask = 0;
+
+	if (!npins)
+		return -EINVAL;
+
+	function = ur_get_group_function(pctldev, group_selector, 0);
+	if (!function)
+		return -EINVAL;
+
+	for (u32 i = 0; i < npins; i++)
+		group_mask |= BIT_ULL(pins[i]);
+
+	return ur_find_group_route(pctrl, function, group_mask, route_out);
+}
+
+static bool ur_function_is_gpio(struct pinctrl_dev *pctldev,
+				unsigned int selector)
+{
+	const struct function_desc *function;
+
+	function = pinmux_generic_get_function(pctldev, selector);
+	if (!function)
+		return false;
+
+	for (u32 i = 0; i < function->func->ngroups; i++) {
+		const char *func_name;
+		int group_selector;
+
+		group_selector = pinctrl_get_group_selector(pctldev,
+							    function->func->groups[i]);
+		if (group_selector < 0)
+			return false;
+
+		func_name = ur_get_group_function(pctldev, group_selector, 0);
+		if (!func_name || strcmp(func_name, "gpio"))
+			return false;
+	}
+
+	return true;
+}
+
+static const struct pinctrl_ops ur_pinctrl_ops = {
+	.get_groups_count = pinctrl_generic_get_group_count,
+	.get_group_name = pinctrl_generic_get_group_name,
+	.get_group_pins = pinctrl_generic_get_group_pins,
+	.dt_node_to_map = pinctrl_generic_pins_function_dt_node_to_map,
+	.dt_free_map = pinconf_generic_dt_free_map,
+};
+
+static int ur_gpio_request_enable(struct pinctrl_dev *pctldev,
+				  struct pinctrl_gpio_range *range,
+				  unsigned int offset)
+{
+	struct ur_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+	const struct ur_port_desc *port_desc;
+	const struct ur_func_route *route;
+	int ret;
+
+	(void)range;
+
+	port_desc = ur_get_pin_port(pctldev, offset);
+	if (!port_desc || !port_desc->supports_gpio)
+		return -EINVAL;
+
+	ret = ur_find_group_route(pctrl, "gpio", BIT_ULL(offset), &route);
+	if (ret)
+		return ret;
+
+	return ur_set_pin_mux_by_num(pctrl, offset, route->mode);
+}
+
+static int ur_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector,
+		      unsigned int group_selector)
+{
+	struct ur_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+	const struct ur_func_route *route;
+	const unsigned int *pins;
+	unsigned int npins;
+	int ret;
+
+	(void)func_selector;
+
+	ret = pinctrl_generic_get_group_pins(pctldev, group_selector, &pins, &npins);
+	if (ret)
+		return ret;
+
+	ret = ur_resolve_group_mux(pctldev, pctrl, group_selector, pins, npins,
+				   &route);
+	if (ret)
+		return ret;
+
+	for (u32 i = 0; i < npins; i++) {
+		ret = ur_set_pin_mux_by_num(pctrl, pins[i], route->mode);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static const struct pinmux_ops ur_pinmux_ops = {
+	.get_functions_count = pinmux_generic_get_function_count,
+	.get_function_name = pinmux_generic_get_function_name,
+	.get_function_groups = pinmux_generic_get_function_groups,
+	.function_is_gpio = ur_function_is_gpio,
+	.set_mux = ur_set_mux,
+	.gpio_request_enable = ur_gpio_request_enable,
+	.strict = true,
+};
+
+static int ur_pin_config_get(struct pinctrl_dev *pctldev,
+			     unsigned int pin,
+			     unsigned long *config)
+{
+	struct ur_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+	u32 conf;
+	int ret;
+
+	ret = ur_read_pin_conf(pctrl, pin, &conf);
+	if (ret)
+		return ret;
+
+	return ur_hw_to_config(config, conf);
+}
+
+static int ur_pin_config_set(struct pinctrl_dev *pctldev,
+			     unsigned int pin,
+			     unsigned long *configs,
+			     unsigned int num_configs)
+{
+	struct ur_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+	u32 conf;
+	int ret;
+
+	ret = ur_read_pin_conf(pctrl, pin, &conf);
+	if (ret)
+		return ret;
+
+	for (u32 i = 0; i < num_configs; i++) {
+		ret = ur_config_to_hw(configs[i], &conf);
+		if (ret)
+			return ret;
+	}
+
+	return ur_write_pin_conf(pctrl, pin, conf);
+}
+
+static int ur_pin_config_group_get(struct pinctrl_dev *pctldev,
+				   unsigned int selector,
+				   unsigned long *config)
+{
+	const unsigned int *pins;
+	unsigned int npins;
+	int ret;
+
+	ret = pinctrl_generic_get_group_pins(pctldev, selector, &pins, &npins);
+	if (ret || !npins)
+		return ret ?: -EINVAL;
+
+	return ur_pin_config_get(pctldev, pins[0], config);
+}
+
+static int ur_pin_config_group_set(struct pinctrl_dev *pctldev,
+				   unsigned int selector,
+				   unsigned long *configs,
+				   unsigned int num_configs)
+{
+	const unsigned int *pins;
+	unsigned int npins;
+	int ret;
+
+	ret = pinctrl_generic_get_group_pins(pctldev, selector, &pins, &npins);
+	if (ret)
+		return ret;
+
+	for (u32 i = 0; i < npins; i++) {
+		ret = ur_pin_config_set(pctldev, pins[i], configs, num_configs);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static const struct pinconf_ops ur_pinconf_ops = {
+	.pin_config_get = ur_pin_config_get,
+	.pin_config_set = ur_pin_config_set,
+	.pin_config_group_get = ur_pin_config_group_get,
+	.pin_config_group_set = ur_pin_config_group_set,
+#ifdef CONFIG_GENERIC_PINCONF
+	.is_generic = true,
+	.pin_config_config_dbg_show = pinconf_generic_dump_config,
+#endif
+};
+
+int ur_pinctrl_probe(struct platform_device *pdev,
+		     const struct ur_pinctrl_data *data)
+{
+	struct pinctrl_desc *desc;
+	struct ur_pinctrl *pctrl;
+	int ret;
+
+	if (!data)
+		return -ENODEV;
+
+	desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL);
+	if (!desc)
+		return -ENOMEM;
+
+	pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
+	if (!pctrl)
+		return -ENOMEM;
+
+	pctrl->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(pctrl->base))
+		return PTR_ERR(pctrl->base);
+	pctrl->dev = &pdev->dev;
+	pctrl->data = data;
+
+	raw_spin_lock_init(&pctrl->lock);
+
+	desc->name = dev_name(&pdev->dev);
+	desc->owner = THIS_MODULE;
+	desc->pins = data->pins;
+	desc->npins = data->npins;
+	desc->pctlops = &ur_pinctrl_ops;
+	desc->pmxops = &ur_pinmux_ops;
+	desc->confops = &ur_pinconf_ops;
+
+	ret = devm_pinctrl_register_and_init(&pdev->dev, desc, pctrl, &pctrl->pctl_dev);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "failed to register pinctrl\n");
+
+	platform_set_drvdata(pdev, pctrl);
+
+	return pinctrl_enable(pctrl->pctl_dev);
+}
+EXPORT_SYMBOL_GPL(ur_pinctrl_probe);
+
+MODULE_DESCRIPTION("UltraRISC pinctrl core driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/ultrarisc/pinctrl-ultrarisc.h b/drivers/pinctrl/ultrarisc/pinctrl-ultrarisc.h
new file mode 100644
index 000000000000..c874688aafca
--- /dev/null
+++ b/drivers/pinctrl/ultrarisc/pinctrl-ultrarisc.h
@@ -0,0 +1,63 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2026 UltraRISC Technology (Shanghai) Co., Ltd.
+ *
+ * Author: Jia Wang <wangjia@ultrarisc.com>
+ */
+
+#ifndef __PINCTRL_ULTRARISC_H__
+#define __PINCTRL_ULTRARISC_H__
+
+#include <linux/io.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/spinlock.h>
+
+struct platform_device;
+
+#define UR_FUNC_DEFAULT		0U
+#define UR_FUNC_0		1U
+#define UR_FUNC_1		0x10000U
+
+#define UR_MAX_PINS_PER_PORT	16
+
+#define UR_BIAS_MASK		0x0000000F
+#define UR_PULL_MASK		0x0C
+#define UR_PULL_DIS		0
+#define UR_PULL_UP		1
+#define UR_PULL_DOWN		2
+#define UR_DRIVE_MASK		0x03
+
+struct ur_port_desc {
+	u32 pin_base;
+	u32 npins;
+	u32 func_offset;
+	u32 conf_offset;
+	u32 supported_modes;
+	bool supports_gpio;
+};
+
+struct ur_func_route {
+	const char *function;
+	u32 mode;
+	u64 valid_pins;
+};
+
+struct ur_pinctrl_data {
+	const struct pinctrl_pin_desc *pins;
+	u32 npins;
+	const struct ur_func_route *routes;
+	u32 num_routes;
+};
+
+struct ur_pinctrl {
+	struct device *dev;
+	struct pinctrl_dev *pctl_dev;
+	const struct ur_pinctrl_data *data;
+	void __iomem *base;
+	raw_spinlock_t lock; /* Protects mux and conf registers */
+};
+
+int ur_pinctrl_probe(struct platform_device *pdev,
+		     const struct ur_pinctrl_data *data);
+
+#endif

-- 
2.34.1



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: pinctrl: Add UltraRISC DP1000 pinctrl controller
  2026-06-08  7:50 ` [PATCH v3 1/2] dt-bindings: pinctrl: Add UltraRISC DP1000 pinctrl controller Jia Wang via B4 Relay
@ 2026-06-08  7:57   ` sashiko-bot
  0 siblings, 0 replies; 4+ messages in thread
From: sashiko-bot @ 2026-06-08  7:57 UTC (permalink / raw)
  To: Jia Wang via B4 Relay; +Cc: devicetree, robh, conor+dt

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The newly added dt-bindings header file is not tracked in the MAINTAINERS entry.
--

commit f7f86b1233735eea88a3047d747f41d13c3dc00b
Author: Jia Wang <wangjia@ultrarisc.com>

dt-bindings: pinctrl: Add UltraRISC DP1000 pinctrl controller

This commit adds device tree binding documentation for the pin controllers 
on the UltraRISC DP1000 RISC-V SoC. It also introduces a new header file 
containing the corresponding pin definitions.

> diff --git a/MAINTAINERS b/MAINTAINERS
> --- a/MAINTAINERS
> +++ b/MAINTAINERS

[ ... ]

> @@ -27357,6 +27357,12 @@ S:	Maintained
>  F:	drivers/usb/common/ulpi.c
>  F:	include/linux/ulpi/
>  
> +ULTRARISC DP1000 PINCTRL DRIVER
> +M:	Jia Wang <wangjia@ultrarisc.com>
> +L:	linux-gpio@vger.kernel.org
> +S:	Maintained
> +F:	Documentation/devicetree/bindings/pinctrl/ultrarisc,dp1000-pinctrl.yaml
> +

[Severity: Low]
This isn't a bug, but should the new header file
include/dt-bindings/pinctrl/ultrarisc,dp1000-pinctrl.h be added to this
MAINTAINERS block as well? Without it, get_maintainer.pl might miss CCing
the maintainer on future patches that modify the pin definitions.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260608-ultrarisc-pinctrl-v3-0-30a09ed74275@ultrarisc.com?part=1

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-06-08  7:57 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-08  7:50 [PATCH v3 0/2] pinctrl: ultrarisc: add DP1000 pinctrl support Jia Wang via B4 Relay
2026-06-08  7:50 ` [PATCH v3 1/2] dt-bindings: pinctrl: Add UltraRISC DP1000 pinctrl controller Jia Wang via B4 Relay
2026-06-08  7:57   ` sashiko-bot
2026-06-08  7:50 ` [PATCH v3 2/2] pinctrl: ultrarisc: Add UltraRISC DP1000 pinctrl driver Jia Wang via B4 Relay

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