* [PATCH v19 0/3] Add OpenCores PTC PWM support
@ 2026-06-15 15:57 Hal Feng
2026-06-15 15:57 ` [PATCH v19 1/3] dt-bindings: pwm: opencores: Update compatibles, examples and maintainers Hal Feng
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Hal Feng @ 2026-06-15 15:57 UTC (permalink / raw)
To: Uwe Kleine-König, Philipp Zabel, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Emil Renner Berthing,
Palmer Dabbelt, Paul Walmsley, Albert Ou
Cc: Hal Feng, linux-pwm, devicetree, linux-riscv, linux-kernel
Add OpenCores PTC PWM driver which is used in StarFive
JH7100/JH7110/JHB100 SoC.
I will maintain this pwm module in place of William.
Changes since v18:
- Address Sashiko AI review comments for the OpenCores PWM driver.
- Fix runtime PM usage count handling on probe, error paths, PWM release
and driver teardown.
- Reject period or duty cycle values below the hardware minimum.
- Restore PWM registers across system sleep resume.
- Return the real error from devm_pwmchip_alloc().
- Preserve bootloader-configured PWM state during probe and keep runtime
PM active if the PWM is already enabled.
- Use synchronous runtime PM put before possible teardown.
Changes since v17:
- Simplify the code. Make it more readable.
- Restructure the driver to register the pwm chip for one pwm channel,
because each OpenCores PTC IP core only supports one PWM channel.
Drop starfive compatibles.
Add patches to fix the dt-bindings and device tree.
- Support runtime pm and system sleep pm.
- Disable the pwm module and reset the pwm counter before updating the
period and duty cycle.
- Improve the descriptions.
- Update the dt-bindings maintainer to Hal Feng.
History:
v18: https://lore.kernel.org/all/20260515054723.25024-1-hal.feng@starfivetech.com/
v17: https://lore.kernel.org/all/20250106103540.10079-1-william.qiu@starfivetech.com/
Hal Feng (3):
dt-bindings: pwm: opencores: Update compatibles, examples and
maintainers
riscv: dts: starfive: Correct pwm nodes
pwm: Add OpenCores PTC PWM driver
.../bindings/pwm/opencores,pwm.yaml | 16 +-
MAINTAINERS | 6 +
.../boot/dts/starfive/jh7100-common.dtsi | 28 +-
arch/riscv/boot/dts/starfive/jh7100.dtsi | 67 +++-
.../boot/dts/starfive/jh7110-common.dtsi | 27 +-
.../boot/dts/starfive/jh7110-milkv-mars.dts | 6 +-
.../dts/starfive/jh7110-milkv-marscm.dtsi | 6 +-
.../dts/starfive/jh7110-pine64-star64.dts | 6 +-
.../jh7110-starfive-visionfive-2-lite.dtsi | 6 +-
.../jh7110-starfive-visionfive-2.dtsi | 6 +-
arch/riscv/boot/dts/starfive/jh7110.dtsi | 67 +++-
drivers/pwm/Kconfig | 12 +
drivers/pwm/Makefile | 1 +
drivers/pwm/pwm-ocores.c | 312 ++++++++++++++++++
14 files changed, 538 insertions(+), 28 deletions(-)
create mode 100644 drivers/pwm/pwm-ocores.c
base-commit: 95e56f0f293ef797123eb032f78f5b5d56a035a6
--
2.43.2
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v19 1/3] dt-bindings: pwm: opencores: Update compatibles, examples and maintainers
2026-06-15 15:57 [PATCH v19 0/3] Add OpenCores PTC PWM support Hal Feng
@ 2026-06-15 15:57 ` Hal Feng
2026-06-15 16:21 ` Conor Dooley
2026-06-15 16:24 ` sashiko-bot
2026-06-15 15:57 ` [PATCH v19 2/3] riscv: dts: starfive: Correct pwm nodes Hal Feng
2026-06-15 15:57 ` [PATCH v19 3/3] pwm: Add OpenCores PTC PWM driver Hal Feng
2 siblings, 2 replies; 7+ messages in thread
From: Hal Feng @ 2026-06-15 15:57 UTC (permalink / raw)
To: Uwe Kleine-König, Philipp Zabel, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Emil Renner Berthing,
Palmer Dabbelt, Paul Walmsley, Albert Ou
Cc: Hal Feng, linux-pwm, devicetree, linux-riscv, linux-kernel
Remove the jh8100 compatible since the JH8100 SoC has been canceled and
will not be released. Add the jhb100 compatible to replace it.
Use a oneOf construct to support the single-string opencores,pwm-v1
compatible.
Change the register size in examples to 0x10, since an OpenCores PTC IP
has only 4 32-bit registers: CNTR, HRC, LRC and CTRL.
I will maintain this pwm module in place of William.
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
---
.../devicetree/bindings/pwm/opencores,pwm.yaml | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/Documentation/devicetree/bindings/pwm/opencores,pwm.yaml b/Documentation/devicetree/bindings/pwm/opencores,pwm.yaml
index 52a59d245cdb..5f05606a2d3d 100644
--- a/Documentation/devicetree/bindings/pwm/opencores,pwm.yaml
+++ b/Documentation/devicetree/bindings/pwm/opencores,pwm.yaml
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: OpenCores PWM controller
maintainers:
- - William Qiu <william.qiu@starfivetech.com>
+ - Hal Feng <hal.feng@starfivetech.com>
description:
The OpenCores PTC ip core contains a PWM controller. When operating in PWM
@@ -19,12 +19,14 @@ allOf:
properties:
compatible:
- items:
- - enum:
- - starfive,jh7100-pwm
- - starfive,jh7110-pwm
- - starfive,jh8100-pwm
+ oneOf:
- const: opencores,pwm-v1
+ - items:
+ - enum:
+ - starfive,jh7100-pwm
+ - starfive,jh7110-pwm
+ - starfive,jhb100-pwm
+ - const: opencores,pwm-v1
reg:
maxItems: 1
@@ -49,7 +51,7 @@ examples:
- |
pwm@12490000 {
compatible = "starfive,jh7110-pwm", "opencores,pwm-v1";
- reg = <0x12490000 0x10000>;
+ reg = <0x12490000 0x10>;
clocks = <&clkgen 181>;
resets = <&rstgen 109>;
#pwm-cells = <3>;
--
2.43.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v19 2/3] riscv: dts: starfive: Correct pwm nodes
2026-06-15 15:57 [PATCH v19 0/3] Add OpenCores PTC PWM support Hal Feng
2026-06-15 15:57 ` [PATCH v19 1/3] dt-bindings: pwm: opencores: Update compatibles, examples and maintainers Hal Feng
@ 2026-06-15 15:57 ` Hal Feng
2026-06-15 15:57 ` [PATCH v19 3/3] pwm: Add OpenCores PTC PWM driver Hal Feng
2 siblings, 0 replies; 7+ messages in thread
From: Hal Feng @ 2026-06-15 15:57 UTC (permalink / raw)
To: Uwe Kleine-König, Philipp Zabel, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Emil Renner Berthing,
Palmer Dabbelt, Paul Walmsley, Albert Ou
Cc: Hal Feng, linux-pwm, devicetree, linux-riscv, linux-kernel
Each of the StarFive JH7100/JH7110 SoCs has 8 OpenCores PTC IP
cores. One OpenCores PTC IP core can output one PWM channel.
Change the register size to 0x10, since an OpenCores PTC IP
has only 4 32-bit registers: CNTR, HRC, LRC and CTRL.
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
---
.../boot/dts/starfive/jh7100-common.dtsi | 28 ++++++--
arch/riscv/boot/dts/starfive/jh7100.dtsi | 67 ++++++++++++++++++-
.../boot/dts/starfive/jh7110-common.dtsi | 27 ++++++--
.../boot/dts/starfive/jh7110-milkv-mars.dts | 6 +-
.../dts/starfive/jh7110-milkv-marscm.dtsi | 6 +-
.../dts/starfive/jh7110-pine64-star64.dts | 6 +-
.../jh7110-starfive-visionfive-2-lite.dtsi | 6 +-
.../jh7110-starfive-visionfive-2.dtsi | 6 +-
arch/riscv/boot/dts/starfive/jh7110.dtsi | 67 ++++++++++++++++++-
9 files changed, 198 insertions(+), 21 deletions(-)
diff --git a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
index ae1a6aeb0aea..85106545090e 100644
--- a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
@@ -199,13 +199,23 @@ GPO_I2C2_PAD_SDA_OEN,
};
};
- pwm_pins: pwm-0 {
- pwm-pins {
+ pwm0_pins: pwm0-0 {
+ pwm0-pins {
pinmux = <GPIOMUX(7,
GPO_PWM_PAD_OUT_BIT0,
GPO_PWM_PAD_OE_N_BIT0,
- GPI_NONE)>,
- <GPIOMUX(5,
+ GPI_NONE)>;
+ bias-disable;
+ drive-strength = <35>;
+ input-disable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+ };
+
+ pwm1_pins: pwm1-0 {
+ pwm1-pins {
+ pinmux = <GPIOMUX(5,
GPO_PWM_PAD_OUT_BIT1,
GPO_PWM_PAD_OE_N_BIT1,
GPI_NONE)>;
@@ -359,9 +369,15 @@ &osc_aud {
clock-frequency = <27000000>;
};
-&pwm {
+&pwm0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_pins>;
+ status = "okay";
+};
+
+&pwm1 {
pinctrl-names = "default";
- pinctrl-0 = <&pwm_pins>;
+ pinctrl-0 = <&pwm1_pins>;
status = "okay";
};
diff --git a/arch/riscv/boot/dts/starfive/jh7100.dtsi b/arch/riscv/boot/dts/starfive/jh7100.dtsi
index 7de0732b8eab..90438df1f74d 100644
--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
@@ -360,9 +360,72 @@ watchdog@12480000 {
<&rstgen JH7100_RSTN_WDT>;
};
- pwm: pwm@12490000 {
+ pwm0: pwm@12490000 {
compatible = "starfive,jh7100-pwm", "opencores,pwm-v1";
- reg = <0x0 0x12490000 0x0 0x10000>;
+ reg = <0x0 0x12490000 0x0 0x10>;
+ clocks = <&clkgen JH7100_CLK_PWM_APB>;
+ resets = <&rstgen JH7100_RSTN_PWM_APB>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm1: pwm@12490010 {
+ compatible = "starfive,jh7100-pwm", "opencores,pwm-v1";
+ reg = <0x0 0x12490010 0x0 0x10>;
+ clocks = <&clkgen JH7100_CLK_PWM_APB>;
+ resets = <&rstgen JH7100_RSTN_PWM_APB>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm2: pwm@12490020 {
+ compatible = "starfive,jh7100-pwm", "opencores,pwm-v1";
+ reg = <0x0 0x12490020 0x0 0x10>;
+ clocks = <&clkgen JH7100_CLK_PWM_APB>;
+ resets = <&rstgen JH7100_RSTN_PWM_APB>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm3: pwm@12490030 {
+ compatible = "starfive,jh7100-pwm", "opencores,pwm-v1";
+ reg = <0x0 0x12490030 0x0 0x10>;
+ clocks = <&clkgen JH7100_CLK_PWM_APB>;
+ resets = <&rstgen JH7100_RSTN_PWM_APB>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm4: pwm@12498000 {
+ compatible = "starfive,jh7100-pwm", "opencores,pwm-v1";
+ reg = <0x0 0x12498000 0x0 0x10>;
+ clocks = <&clkgen JH7100_CLK_PWM_APB>;
+ resets = <&rstgen JH7100_RSTN_PWM_APB>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm5: pwm@12498010 {
+ compatible = "starfive,jh7100-pwm", "opencores,pwm-v1";
+ reg = <0x0 0x12498010 0x0 0x10>;
+ clocks = <&clkgen JH7100_CLK_PWM_APB>;
+ resets = <&rstgen JH7100_RSTN_PWM_APB>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm6: pwm@12498020 {
+ compatible = "starfive,jh7100-pwm", "opencores,pwm-v1";
+ reg = <0x0 0x12498020 0x0 0x10>;
+ clocks = <&clkgen JH7100_CLK_PWM_APB>;
+ resets = <&rstgen JH7100_RSTN_PWM_APB>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm7: pwm@12498030 {
+ compatible = "starfive,jh7100-pwm", "opencores,pwm-v1";
+ reg = <0x0 0x12498030 0x0 0x10>;
clocks = <&clkgen JH7100_CLK_PWM_APB>;
resets = <&rstgen JH7100_RSTN_PWM_APB>;
#pwm-cells = <3>;
diff --git a/arch/riscv/boot/dts/starfive/jh7110-common.dtsi b/arch/riscv/boot/dts/starfive/jh7110-common.dtsi
index a7a1c09a2c90..64de468f2c31 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-common.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110-common.dtsi
@@ -326,9 +326,14 @@ uboot@100000 {
};
};
-&pwm {
+&pwm0 {
pinctrl-names = "default";
- pinctrl-0 = <&pwm_pins>;
+ pinctrl-0 = <&pwm0_pins>;
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm1_pins>;
};
&spi0 {
@@ -528,12 +533,22 @@ GPOEN_ENABLE,
};
};
- pwm_pins: pwm-0 {
- pwm-pins {
+ pwm0_pins: pwm0-0 {
+ pwm0-pins {
pinmux = <GPIOMUX(46, GPOUT_SYS_PWM_CHANNEL0,
GPOEN_SYS_PWM0_CHANNEL0,
- GPI_NONE)>,
- <GPIOMUX(59, GPOUT_SYS_PWM_CHANNEL1,
+ GPI_NONE)>;
+ bias-disable;
+ drive-strength = <12>;
+ input-disable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+ };
+
+ pwm1_pins: pwm1-0 {
+ pwm1-pins {
+ pinmux = <GPIOMUX(59, GPOUT_SYS_PWM_CHANNEL1,
GPOEN_SYS_PWM0_CHANNEL1,
GPI_NONE)>;
bias-disable;
diff --git a/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
index 21873612d993..54013c70f4b4 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
+++ b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
@@ -68,7 +68,11 @@ &phy0 {
motorcomm,tx-clk-adj-enabled;
};
-&pwm {
+&pwm0 {
+ status = "okay";
+};
+
+&pwm1 {
status = "okay";
};
diff --git a/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm.dtsi b/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm.dtsi
index 025471061d43..31afac27b86d 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm.dtsi
@@ -87,7 +87,11 @@ &phy0 {
motorcomm,tx-clk-adj-enabled;
};
-&pwm {
+&pwm0 {
+ status = "okay";
+};
+
+&pwm1 {
status = "okay";
};
diff --git a/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts b/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
index aec7ae3d1f5b..a9e82f25efde 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
+++ b/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
@@ -95,7 +95,11 @@ &phy1 {
motorcomm,tx-clk-100-inverted;
};
-&pwm {
+&pwm0 {
+ status = "okay";
+};
+
+&pwm1 {
status = "okay";
};
diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite.dtsi b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite.dtsi
index f8797a666dbf..85b56a72dff7 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite.dtsi
@@ -74,7 +74,11 @@ &phy0 {
tx-internal-delay-ps = <1500>;
};
-&pwm {
+&pwm0 {
+ status = "okay";
+};
+
+&pwm1 {
status = "okay";
};
diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
index edc8f4588133..35208f95cd3d 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
@@ -73,7 +73,11 @@ &pcie1 {
status = "okay";
};
-&pwm {
+&pwm0 {
+ status = "okay";
+};
+
+&pwm1 {
status = "okay";
};
diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
index 9c3e4598747e..82ea63f715b0 100644
--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
@@ -846,9 +846,72 @@ i2stx1: i2s@120c0000 {
status = "disabled";
};
- pwm: pwm@120d0000 {
+ pwm0: pwm@120d0000 {
compatible = "starfive,jh7110-pwm", "opencores,pwm-v1";
- reg = <0x0 0x120d0000 0x0 0x10000>;
+ reg = <0x0 0x120d0000 0x0 0x10>;
+ clocks = <&syscrg JH7110_SYSCLK_PWM_APB>;
+ resets = <&syscrg JH7110_SYSRST_PWM_APB>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm1: pwm@120d0010 {
+ compatible = "starfive,jh7110-pwm", "opencores,pwm-v1";
+ reg = <0x0 0x120d0010 0x0 0x10>;
+ clocks = <&syscrg JH7110_SYSCLK_PWM_APB>;
+ resets = <&syscrg JH7110_SYSRST_PWM_APB>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm2: pwm@120d0020 {
+ compatible = "starfive,jh7110-pwm", "opencores,pwm-v1";
+ reg = <0x0 0x120d0020 0x0 0x10>;
+ clocks = <&syscrg JH7110_SYSCLK_PWM_APB>;
+ resets = <&syscrg JH7110_SYSRST_PWM_APB>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm3: pwm@120d0030 {
+ compatible = "starfive,jh7110-pwm", "opencores,pwm-v1";
+ reg = <0x0 0x120d0030 0x0 0x10>;
+ clocks = <&syscrg JH7110_SYSCLK_PWM_APB>;
+ resets = <&syscrg JH7110_SYSRST_PWM_APB>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm4: pwm@120d8000 {
+ compatible = "starfive,jh7110-pwm", "opencores,pwm-v1";
+ reg = <0x0 0x120d8000 0x0 0x10>;
+ clocks = <&syscrg JH7110_SYSCLK_PWM_APB>;
+ resets = <&syscrg JH7110_SYSRST_PWM_APB>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm5: pwm@120d8010 {
+ compatible = "starfive,jh7110-pwm", "opencores,pwm-v1";
+ reg = <0x0 0x120d8010 0x0 0x10>;
+ clocks = <&syscrg JH7110_SYSCLK_PWM_APB>;
+ resets = <&syscrg JH7110_SYSRST_PWM_APB>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm6: pwm@120d8020 {
+ compatible = "starfive,jh7110-pwm", "opencores,pwm-v1";
+ reg = <0x0 0x120d8020 0x0 0x10>;
+ clocks = <&syscrg JH7110_SYSCLK_PWM_APB>;
+ resets = <&syscrg JH7110_SYSRST_PWM_APB>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm7: pwm@120d8030 {
+ compatible = "starfive,jh7110-pwm", "opencores,pwm-v1";
+ reg = <0x0 0x120d8030 0x0 0x10>;
clocks = <&syscrg JH7110_SYSCLK_PWM_APB>;
resets = <&syscrg JH7110_SYSRST_PWM_APB>;
#pwm-cells = <3>;
--
2.43.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v19 3/3] pwm: Add OpenCores PTC PWM driver
2026-06-15 15:57 [PATCH v19 0/3] Add OpenCores PTC PWM support Hal Feng
2026-06-15 15:57 ` [PATCH v19 1/3] dt-bindings: pwm: opencores: Update compatibles, examples and maintainers Hal Feng
2026-06-15 15:57 ` [PATCH v19 2/3] riscv: dts: starfive: Correct pwm nodes Hal Feng
@ 2026-06-15 15:57 ` Hal Feng
2026-06-15 16:25 ` sashiko-bot
2 siblings, 1 reply; 7+ messages in thread
From: Hal Feng @ 2026-06-15 15:57 UTC (permalink / raw)
To: Uwe Kleine-König, Philipp Zabel, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Emil Renner Berthing,
Palmer Dabbelt, Paul Walmsley, Albert Ou
Cc: Hal Feng, linux-pwm, devicetree, linux-riscv, linux-kernel
Add PWM driver for OpenCores PTC IP core.
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
---
MAINTAINERS | 6 +
drivers/pwm/Kconfig | 12 ++
drivers/pwm/Makefile | 1 +
drivers/pwm/pwm-ocores.c | 312 +++++++++++++++++++++++++++++++++++++++
4 files changed, 331 insertions(+)
create mode 100644 drivers/pwm/pwm-ocores.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 0d94420eae3d..b6a004f2e6c6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20035,6 +20035,12 @@ F: Documentation/i2c/busses/i2c-ocores.rst
F: drivers/i2c/busses/i2c-ocores.c
F: include/linux/platform_data/i2c-ocores.h
+OPENCORES PWM DRIVER
+M: Hal Feng <hal.feng@starfivetech.com>
+S: Supported
+F: Documentation/devicetree/bindings/pwm/opencores,pwm.yaml
+F: drivers/pwm/pwm-ocores.c
+
OPENRISC ARCHITECTURE
M: Jonas Bonn <jonas@southpole.se>
M: Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 6f3147518376..dd7f3bf5c3eb 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -534,6 +534,18 @@ config PWM_NTXEC
controller found in certain e-book readers designed by the original
design manufacturer Netronix.
+config PWM_OCORES
+ tristate "OpenCores PTC PWM support"
+ depends on HAS_IOMEM && OF
+ depends on COMMON_CLK
+ depends on ARCH_STARFIVE || COMPILE_TEST
+ help
+ PWM driver for OpenCores PTC IP core.
+ For details see https://opencores.org/projects/ptc.
+
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-ocores.
+
config PWM_OMAP_DMTIMER
tristate "OMAP Dual-Mode Timer PWM support"
depends on OF
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 0dc0d2b69025..2d47bad7bd74 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_PWM_MICROCHIP_CORE) += pwm-microchip-core.o
obj-$(CONFIG_PWM_MTK_DISP) += pwm-mtk-disp.o
obj-$(CONFIG_PWM_MXS) += pwm-mxs.o
obj-$(CONFIG_PWM_NTXEC) += pwm-ntxec.o
+obj-$(CONFIG_PWM_OCORES) += pwm-ocores.o
obj-$(CONFIG_PWM_OMAP_DMTIMER) += pwm-omap-dmtimer.o
obj-$(CONFIG_PWM_PCA9685) += pwm-pca9685.o
obj-$(CONFIG_PWM_PXA) += pwm-pxa.o
diff --git a/drivers/pwm/pwm-ocores.c b/drivers/pwm/pwm-ocores.c
new file mode 100644
index 000000000000..b126933d9922
--- /dev/null
+++ b/drivers/pwm/pwm-ocores.c
@@ -0,0 +1,312 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * OpenCores PTC PWM Driver
+ *
+ * https://opencores.org/projects/ptc
+ *
+ * Copyright (C) 2018-2026 StarFive Technology Co., Ltd.
+ *
+ * Limitations:
+ * - The hardware only supports inverted polarity.
+ * - The hardware minimum period / duty_cycle of PWM is (1 / pwm_apb clock frequency).
+ * - The hardware maximum period / duty_cycle of PWM is (U32_MAX / pwm_apb clock frequency).
+ * - The output is immediately set to low when the module is disabled.
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/pwm.h>
+#include <linux/reset.h>
+
+#define OCPWM_HRC 0x4
+#define OCPWM_LRC 0x8
+#define OCPWM_CTRL 0xC
+
+#define OCPWM_CTRL_EN BIT(0)
+#define OCPWM_CTRL_OE BIT(3)
+#define OCPWM_CTRL_RST BIT(7)
+
+#define OCPWM_NUM_SAVED_REGS 3
+
+struct ocores_pwm_device {
+ void __iomem *base;
+ struct clk *clk;
+ unsigned long clk_rate;
+ struct reset_control *rst;
+ u32 saved_regs[OCPWM_NUM_SAVED_REGS];
+};
+
+static int ocores_pwm_get_state(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ struct pwm_state *state)
+{
+ struct ocores_pwm_device *ddata = pwmchip_get_drvdata(chip);
+ u32 period_data, duty_data, ctrl_data;
+ int ret;
+
+ ret = pm_runtime_resume_and_get(pwmchip_parent(chip));
+ if (ret < 0)
+ return ret;
+
+ period_data = readl(ddata->base + OCPWM_LRC);
+ duty_data = readl(ddata->base + OCPWM_HRC);
+ ctrl_data = readl(ddata->base + OCPWM_CTRL);
+
+ state->period = DIV_ROUND_UP_ULL((u64)period_data * NSEC_PER_SEC, ddata->clk_rate);
+ state->duty_cycle = DIV_ROUND_UP_ULL((u64)duty_data * NSEC_PER_SEC, ddata->clk_rate);
+ if (state->duty_cycle > state->period)
+ state->duty_cycle = state->period;
+
+ state->polarity = PWM_POLARITY_INVERSED;
+ state->enabled = (ctrl_data & OCPWM_CTRL_EN) ? true : false;
+
+ pm_runtime_put(pwmchip_parent(chip));
+
+ return 0;
+}
+
+static int ocores_pwm_apply(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ const struct pwm_state *state)
+{
+ struct ocores_pwm_device *ddata = pwmchip_get_drvdata(chip);
+ bool was_enabled = pwm_is_enabled(pwm);
+ u64 period_data, duty_data;
+ int ret;
+
+ if (state->polarity != PWM_POLARITY_INVERSED)
+ return -EINVAL;
+
+ if (state->enabled) {
+ if (!was_enabled) {
+ ret = pm_runtime_resume_and_get(pwmchip_parent(chip));
+ if (ret < 0)
+ return ret;
+ }
+ } else {
+ if (was_enabled) {
+ writel(0, ddata->base + OCPWM_CTRL);
+ pm_runtime_put(pwmchip_parent(chip));
+ }
+ return 0;
+ }
+
+ writel(0, ddata->base + OCPWM_CTRL);
+ writel(OCPWM_CTRL_RST, ddata->base + OCPWM_CTRL);
+
+ period_data = mul_u64_u32_div(state->period, ddata->clk_rate, NSEC_PER_SEC);
+ if (period_data > U32_MAX)
+ period_data = U32_MAX;
+
+ duty_data = mul_u64_u32_div(state->duty_cycle, ddata->clk_rate, NSEC_PER_SEC);
+ if (duty_data > U32_MAX)
+ duty_data = U32_MAX;
+
+ if (!period_data || !duty_data) {
+ if (!was_enabled)
+ pm_runtime_put(pwmchip_parent(chip));
+ return -EINVAL;
+ }
+
+ writel(period_data, ddata->base + OCPWM_LRC);
+ writel(duty_data, ddata->base + OCPWM_HRC);
+ writel(OCPWM_CTRL_OE | OCPWM_CTRL_EN, ddata->base + OCPWM_CTRL);
+
+ return 0;
+}
+
+static void ocores_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct ocores_pwm_device *ddata = pwmchip_get_drvdata(chip);
+
+ if (pwm_is_enabled(pwm)) {
+ writel(0, ddata->base + OCPWM_CTRL);
+ pm_runtime_put_sync(pwmchip_parent(chip));
+ }
+}
+
+static const struct pwm_ops ocores_pwm_ops = {
+ .get_state = ocores_pwm_get_state,
+ .apply = ocores_pwm_apply,
+ .free = ocores_pwm_free,
+};
+
+static int ocores_pwm_runtime_suspend(struct device *dev)
+{
+ struct ocores_pwm_device *ddata = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(ddata->clk);
+
+ return 0;
+}
+
+static int ocores_pwm_runtime_resume(struct device *dev)
+{
+ struct ocores_pwm_device *ddata = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(ddata->clk);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to enable clock\n");
+
+ return 0;
+}
+
+static int __maybe_unused ocores_pwm_suspend(struct device *dev)
+{
+ struct ocores_pwm_device *ddata = dev_get_drvdata(dev);
+ int ret, i;
+
+ ret = pm_runtime_resume_and_get(dev);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < OCPWM_NUM_SAVED_REGS; i++)
+ ddata->saved_regs[i] = readl(ddata->base + 4 + 4 * i);
+
+ pm_runtime_put_sync(dev);
+
+ return pm_runtime_force_suspend(dev);
+}
+
+static int __maybe_unused ocores_pwm_resume(struct device *dev)
+{
+ struct ocores_pwm_device *ddata = dev_get_drvdata(dev);
+ int ret, i;
+
+ ret = pm_runtime_force_resume(dev);
+ if (ret)
+ return ret;
+
+ ret = pm_runtime_resume_and_get(dev);
+ if (ret < 0)
+ return ret;
+
+ writel(0, ddata->base + OCPWM_CTRL);
+ writel(OCPWM_CTRL_RST, ddata->base + OCPWM_CTRL);
+ for (i = 0; i < OCPWM_NUM_SAVED_REGS; i++)
+ writel(ddata->saved_regs[i], ddata->base + 4 + 4 * i);
+
+ pm_runtime_put_sync(dev);
+
+ return 0;
+}
+
+static const struct dev_pm_ops ocores_pwm_pm_ops = {
+ RUNTIME_PM_OPS(ocores_pwm_runtime_suspend,
+ ocores_pwm_runtime_resume, NULL)
+ SYSTEM_SLEEP_PM_OPS(ocores_pwm_suspend, ocores_pwm_resume)
+};
+
+static void ocores_pwm_pm_disable(void *data)
+{
+ struct device *dev = data;
+ struct ocores_pwm_device *ddata = dev_get_drvdata(dev);
+
+ pm_runtime_disable(dev);
+
+ if (!pm_runtime_status_suspended(dev)) {
+ /* Balance probe's pm_runtime_get_noresume() for bootloader-enabled PWM. */
+ if (readl(ddata->base + OCPWM_CTRL) & OCPWM_CTRL_EN)
+ pm_runtime_put_noidle(dev);
+
+ ocores_pwm_runtime_suspend(dev);
+ }
+
+ reset_control_assert(ddata->rst);
+}
+
+static int ocores_pwm_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct ocores_pwm_device *ddata;
+ struct pwm_chip *chip;
+ int ret;
+
+ chip = devm_pwmchip_alloc(dev, 1, sizeof(*ddata));
+ if (IS_ERR(chip))
+ return PTR_ERR(chip);
+
+ chip->ops = &ocores_pwm_ops;
+ ddata = pwmchip_get_drvdata(chip);
+
+ ddata->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(ddata->base))
+ return dev_err_probe(dev, PTR_ERR(ddata->base),
+ "Failed to map IO resources\n");
+
+ ddata->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(ddata->clk))
+ return dev_err_probe(dev, PTR_ERR(ddata->clk),
+ "Failed to get clock\n");
+
+ ddata->clk_rate = clk_get_rate(ddata->clk);
+ if (!ddata->clk_rate || ddata->clk_rate > NSEC_PER_SEC)
+ return dev_err_probe(dev, -EINVAL,
+ "Invalid clock rate: %lu\n", ddata->clk_rate);
+
+ ddata->rst = devm_reset_control_get_optional_shared(dev, NULL);
+ if (IS_ERR(ddata->rst))
+ return dev_err_probe(dev, PTR_ERR(ddata->rst),
+ "Failed to get reset\n");
+
+ platform_set_drvdata(pdev, ddata);
+
+ ret = ocores_pwm_runtime_resume(dev);
+ if (ret)
+ return ret;
+
+ ret = reset_control_deassert(ddata->rst);
+ if (ret)
+ goto err_clk_disable;
+
+ ret = pm_runtime_set_active(dev);
+ if (ret)
+ goto err_reset_assert;
+
+ pm_runtime_get_noresume(dev);
+ pm_runtime_enable(dev);
+
+ if (!(readl(ddata->base + OCPWM_CTRL) & OCPWM_CTRL_EN))
+ pm_runtime_put_sync(dev);
+
+ ret = devm_add_action_or_reset(dev, ocores_pwm_pm_disable, dev);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to add pm disable action\n");
+
+ ret = devm_pwmchip_add(dev, chip);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "Could not register PWM chip\n");
+
+ return 0;
+
+err_reset_assert:
+ reset_control_assert(ddata->rst);
+err_clk_disable:
+ ocores_pwm_runtime_suspend(dev);
+ return dev_err_probe(dev, ret, "Failed to init pwm power\n");
+}
+
+static const struct of_device_id ocores_pwm_of_match[] = {
+ { .compatible = "opencores,pwm-v1" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, ocores_pwm_of_match);
+
+static struct platform_driver ocores_pwm_driver = {
+ .probe = ocores_pwm_probe,
+ .driver = {
+ .name = "ocores-pwm",
+ .of_match_table = ocores_pwm_of_match,
+ .pm = pm_ptr(&ocores_pwm_pm_ops),
+ },
+};
+module_platform_driver(ocores_pwm_driver);
+
+MODULE_AUTHOR("Jieqin Chen");
+MODULE_AUTHOR("Hal Feng <hal.feng@starfivetech.com>");
+MODULE_DESCRIPTION("OpenCores PTC PWM driver");
+MODULE_LICENSE("GPL");
--
2.43.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v19 1/3] dt-bindings: pwm: opencores: Update compatibles, examples and maintainers
2026-06-15 15:57 ` [PATCH v19 1/3] dt-bindings: pwm: opencores: Update compatibles, examples and maintainers Hal Feng
@ 2026-06-15 16:21 ` Conor Dooley
2026-06-15 16:24 ` sashiko-bot
1 sibling, 0 replies; 7+ messages in thread
From: Conor Dooley @ 2026-06-15 16:21 UTC (permalink / raw)
To: Hal Feng
Cc: Uwe Kleine-König, Philipp Zabel, Rob Herring,
Krzysztof Kozlowski, Emil Renner Berthing, Palmer Dabbelt,
Paul Walmsley, Albert Ou, linux-pwm, devicetree, linux-riscv,
linux-kernel
[-- Attachment #1: Type: text/plain, Size: 2289 bytes --]
On Mon, Jun 15, 2026 at 11:57:57PM +0800, Hal Feng wrote:
> Remove the jh8100 compatible since the JH8100 SoC has been canceled and
> will not be released. Add the jhb100 compatible to replace it.
> Use a oneOf construct to support the single-string opencores,pwm-v1
> compatible.
No thanks. Simple as this IP might be, I still want soc-specific
compatibles to be a requirement.
pw-bot: changes-requested
Thanks,
Conor.
>
> Change the register size in examples to 0x10, since an OpenCores PTC IP
> has only 4 32-bit registers: CNTR, HRC, LRC and CTRL.
>
> I will maintain this pwm module in place of William.
>
> Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
> ---
> .../devicetree/bindings/pwm/opencores,pwm.yaml | 16 +++++++++-------
> 1 file changed, 9 insertions(+), 7 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/pwm/opencores,pwm.yaml b/Documentation/devicetree/bindings/pwm/opencores,pwm.yaml
> index 52a59d245cdb..5f05606a2d3d 100644
> --- a/Documentation/devicetree/bindings/pwm/opencores,pwm.yaml
> +++ b/Documentation/devicetree/bindings/pwm/opencores,pwm.yaml
> @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
> title: OpenCores PWM controller
>
> maintainers:
> - - William Qiu <william.qiu@starfivetech.com>
> + - Hal Feng <hal.feng@starfivetech.com>
>
> description:
> The OpenCores PTC ip core contains a PWM controller. When operating in PWM
> @@ -19,12 +19,14 @@ allOf:
>
> properties:
> compatible:
> - items:
> - - enum:
> - - starfive,jh7100-pwm
> - - starfive,jh7110-pwm
> - - starfive,jh8100-pwm
> + oneOf:
> - const: opencores,pwm-v1
> + - items:
> + - enum:
> + - starfive,jh7100-pwm
> + - starfive,jh7110-pwm
> + - starfive,jhb100-pwm
> + - const: opencores,pwm-v1
>
> reg:
> maxItems: 1
> @@ -49,7 +51,7 @@ examples:
> - |
> pwm@12490000 {
> compatible = "starfive,jh7110-pwm", "opencores,pwm-v1";
> - reg = <0x12490000 0x10000>;
> + reg = <0x12490000 0x10>;
> clocks = <&clkgen 181>;
> resets = <&rstgen 109>;
> #pwm-cells = <3>;
> --
> 2.43.2
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v19 1/3] dt-bindings: pwm: opencores: Update compatibles, examples and maintainers
2026-06-15 15:57 ` [PATCH v19 1/3] dt-bindings: pwm: opencores: Update compatibles, examples and maintainers Hal Feng
2026-06-15 16:21 ` Conor Dooley
@ 2026-06-15 16:24 ` sashiko-bot
1 sibling, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-06-15 16:24 UTC (permalink / raw)
To: Hal Feng; +Cc: robh, conor+dt, devicetree
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] Invalid YAML indentation under the `items` block violates the subsystem's yamllint rules, causing `make dt_binding_check` to fail.
--
commit f6d46c997f1ef83c6c55a27e0e3260fdf27add18
Author: Hal Feng <hal.feng@starfivetech.com>
dt-bindings: pwm: opencores: Update compatibles, examples and maintainers
Remove the jh8100 compatible since the JH8100 SoC has been canceled and
will not be released. Add the jhb100 compatible to replace it. Use a oneOf
construct to support the single-string opencores,pwm-v1 compatible.
> diff --git a/Documentation/devicetree/bindings/pwm/opencores,pwm.yaml b/Documentation/devicetree/bindings/pwm/opencores,pwm.yaml
> index 52a59d245cdb1..5f05606a2d3d4 100644
> --- a/Documentation/devicetree/bindings/pwm/opencores,pwm.yaml
> +++ b/Documentation/devicetree/bindings/pwm/opencores,pwm.yaml
[ ... ]
> @@ -19,12 +19,14 @@ allOf:
>
> properties:
> compatible:
> - items:
> - - enum:
> - - starfive,jh7100-pwm
> - - starfive,jh7110-pwm
> - - starfive,jh8100-pwm
> + oneOf:
> - const: opencores,pwm-v1
> + - items:
> + - enum:
> + - starfive,jh7100-pwm
> + - starfive,jh7110-pwm
> + - starfive,jhb100-pwm
> + - const: opencores,pwm-v1
[Severity: Low]
Does this formatting cause make dt_binding_check to fail? It looks like the
YAML sequence markers under the items block are indented to 8 spaces,
matching the parent mapping key, instead of being indented to 10 spaces.
This might violate the yamllint indent-sequences rules.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260615155759.129210-1-hal.feng@starfivetech.com?part=1
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v19 3/3] pwm: Add OpenCores PTC PWM driver
2026-06-15 15:57 ` [PATCH v19 3/3] pwm: Add OpenCores PTC PWM driver Hal Feng
@ 2026-06-15 16:25 ` sashiko-bot
0 siblings, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-06-15 16:25 UTC (permalink / raw)
To: Hal Feng; +Cc: conor+dt, robh, devicetree
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Hardware state corruption and PM runtime leak in `ocores_pwm_apply` on invalid parameter request.
--
commit b3a12f20d0a4ac7f1d2dc7a3d103fe2acf522975
Author: Hal Feng <hal.feng@starfivetech.com>
Subject: pwm: Add OpenCores PTC PWM driver
This commit adds a PWM driver for the OpenCores PTC IP core.
> diff --git a/drivers/pwm/pwm-ocores.c b/drivers/pwm/pwm-ocores.c
> new file mode 100644
> --- /dev/null
> +++ b/drivers/pwm/pwm-ocores.c
[ ... ]
> +static int ocores_pwm_apply(struct pwm_chip *chip,
> + struct pwm_device *pwm,
> + const struct pwm_state *state)
> +{
> + struct ocores_pwm_device *ddata = pwmchip_get_drvdata(chip);
> + bool was_enabled = pwm_is_enabled(pwm);
> + u64 period_data, duty_data;
> + int ret;
> +
> + if (state->polarity != PWM_POLARITY_INVERSED)
> + return -EINVAL;
> +
> + if (state->enabled) {
> + if (!was_enabled) {
> + ret = pm_runtime_resume_and_get(pwmchip_parent(chip));
> + if (ret < 0)
> + return ret;
> + }
> + } else {
> + if (was_enabled) {
> + writel(0, ddata->base + OCPWM_CTRL);
> + pm_runtime_put(pwmchip_parent(chip));
> + }
> + return 0;
> + }
> +
> + writel(0, ddata->base + OCPWM_CTRL);
> + writel(OCPWM_CTRL_RST, ddata->base + OCPWM_CTRL);
> +
> + period_data = mul_u64_u32_div(state->period, ddata->clk_rate, NSEC_PER_SEC);
> + if (period_data > U32_MAX)
> + period_data = U32_MAX;
> +
> + duty_data = mul_u64_u32_div(state->duty_cycle, ddata->clk_rate, NSEC_PER_SEC);
> + if (duty_data > U32_MAX)
> + duty_data = U32_MAX;
> +
> + if (!period_data || !duty_data) {
> + if (!was_enabled)
> + pm_runtime_put(pwmchip_parent(chip));
> + return -EINVAL;
[Severity: High]
Does stopping and resetting the hardware before validating the requested
parameters cause state corruption if the validation fails?
If period_data or duty_data evaluate to 0, the function returns -EINVAL.
Since the hardware was already stopped and reset, the framework's software
state will show the PWM as enabled, but the physical hardware will remain
disabled.
Additionally, if was_enabled is true, does this error path leak the PM
runtime reference?
Since OCPWM_CTRL_EN was prematurely cleared, ocores_pwm_pm_disable() will
later see the enable bit as 0 and skip its pm_runtime_put_noidle() call:
ocores_pwm_pm_disable() {
...
if (!pm_runtime_status_suspended(dev)) {
if (readl(ddata->base + OCPWM_CTRL) & OCPWM_CTRL_EN)
pm_runtime_put_noidle(dev);
...
}
> + }
> +
> + writel(period_data, ddata->base + OCPWM_LRC);
> + writel(duty_data, ddata->base + OCPWM_HRC);
> + writel(OCPWM_CTRL_OE | OCPWM_CTRL_EN, ddata->base + OCPWM_CTRL);
> +
> + return 0;
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260615155759.129210-1-hal.feng@starfivetech.com?part=3
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-06-15 16:32 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-15 15:57 [PATCH v19 0/3] Add OpenCores PTC PWM support Hal Feng
2026-06-15 15:57 ` [PATCH v19 1/3] dt-bindings: pwm: opencores: Update compatibles, examples and maintainers Hal Feng
2026-06-15 16:21 ` Conor Dooley
2026-06-15 16:24 ` sashiko-bot
2026-06-15 15:57 ` [PATCH v19 2/3] riscv: dts: starfive: Correct pwm nodes Hal Feng
2026-06-15 15:57 ` [PATCH v19 3/3] pwm: Add OpenCores PTC PWM driver Hal Feng
2026-06-15 16:25 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox