* Re: [PATCH v6 02/11] ARM: dts: renesas: r8a7740: Add clocks for FSI
From: Geert Uytterhoeven @ 2026-06-12 14:31 UTC (permalink / raw)
To: Bui Duc Phuc
Cc: Kuninori Morimoto, Mark Brown, Liam Girdwood, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Magnus Damm, Jaroslav Kysela,
Takashi Iwai, linux-sound, linux-renesas-soc, devicetree,
linux-kernel
In-Reply-To: <CAABR9nG2kHH3=gkd0H+vhGZJtvkHLA7YMpoWt+p+XtdNV+oe=A@mail.gmail.com>
Hi Phuc,
On Fri, 12 Jun 2026 at 14:54, Bui Duc Phuc <phucduc.bui@gmail.com> wrote:
> > According to my schematics (RevA), R120 is not populated, but R250 is.
> > So the 12.288 MHz clock is fed to both the FSIACK-pin of R-Mobile A1,
> > and the MCLK-pin of the WM8978 codec.
> > Which revision of the schematics and board do you have?
> >
>
> Oh, sorry, I misread it. You're right, mine is also Rev A, and R120 is
> not populated, but R250 is.
>
> > I haven't located R120 and R250 yet, so I don't know which
> > configuration my board has.
>
> Please flip the board over; these resistors are located on the bottom
> side of the board rather than the top.
Thanks, confirmed.
Have a nice weekend!
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* [PATCH v1 0/2] Add support for Synopsys DesignWare SSI controller version 2.00a
From: Changhuang Liang @ 2026-06-12 12:58 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Mark Brown
Cc: linux-spi, linux-kernel, devicetree, Changhuang Liang
Add support for Synopsys DesignWare SSI controller version 2.00a,
which is used on the JHB100 SoC.
Changhuang Liang (2):
dt-bindings: spi: snps,dw-apb-ssi: Add support for snps,dwc-ssi-2.00a
spi: dw: Add support for snps,dwc-ssi-2.00a
Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml | 1 +
drivers/spi/spi-dw-mmio.c | 1 +
2 files changed, 2 insertions(+)
--
2.25.1
^ permalink raw reply
* Re: [PATCH v2 2/7] dt-bindings: bluetooth: qcom,wcn6750-bt: Document WCN6755 Bluetooth
From: Luca Weiss @ 2026-06-12 14:33 UTC (permalink / raw)
To: Luca Weiss, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Alexander Koskovich,
Liam Girdwood, Mark Brown, Bartosz Golaszewski, Marcel Holtmann,
Luiz Augusto von Dentz, Balakrishna Godavarthi, Rocky Liao,
Johannes Berg, Jeff Johnson
Cc: ~postmarketos/upstreaming, phone-devel, linux-arm-msm,
linux-kernel, devicetree, linux-bluetooth, linux-wireless, ath11k
In-Reply-To: <20260403-milos-fp6-bt-wifi-v2-2-393322b27c5f@fairphone.com>
Hi Luiz,
On Fri Apr 3, 2026 at 3:52 PM CEST, Luca Weiss wrote:
> Document the WCN6755 Bluetooth using a fallback to WCN6750 since the two
> chips seem to be completely pin and software compatible. In fact the
> original downstream kernel just pretends the WCN6755 is a WCN6750.
Could you please pick up this patch (or provide an Ack if you want Bjorn
to pick this up with the rest of the series).
Regards
Luca
>
> Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
> ---
> .../devicetree/bindings/net/bluetooth/qcom,wcn6750-bt.yaml | 10 ++++++++--
> 1 file changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/net/bluetooth/qcom,wcn6750-bt.yaml b/Documentation/devicetree/bindings/net/bluetooth/qcom,wcn6750-bt.yaml
> index 8606a45ac9b9..79522409d709 100644
> --- a/Documentation/devicetree/bindings/net/bluetooth/qcom,wcn6750-bt.yaml
> +++ b/Documentation/devicetree/bindings/net/bluetooth/qcom,wcn6750-bt.yaml
> @@ -12,8 +12,14 @@ maintainers:
>
> properties:
> compatible:
> - enum:
> - - qcom,wcn6750-bt
> + oneOf:
> + - items:
> + - enum:
> + - qcom,wcn6755-bt
> + - const: qcom,wcn6750-bt
> +
> + - enum:
> + - qcom,wcn6750-bt
>
> enable-gpios:
> maxItems: 1
^ permalink raw reply
* Re: [PATCH] dt-bindings: PCI: mediatek-gen3: Allow memory-region for restricted DMA buffer
From: Rob Herring (Arm) @ 2026-06-12 14:32 UTC (permalink / raw)
To: Chen-Yu Tsai
Cc: linux-mediatek, linux-kernel, Lorenzo Pieralisi, Conor Dooley,
Ryder Lee, Manivannan Sadhasivam, Bjorn Helgaas,
Krzysztof Wilczyński, Krzysztof Kozlowski, linux-pci,
Matthias Brugger, devicetree, AngeloGioacchino Del Regno
In-Reply-To: <20260508063633.3894348-1-wenst@chromium.org>
On Fri, 08 May 2026 14:36:32 +0800, Chen-Yu Tsai wrote:
> On some SoCs without an IOMMU behind the PCIe controller, the PCIe
> controller memory access could be limited to a small region by the
> firmware configuring a memory protection unit. This memory region
> must be assigned to the PCIe controller so that the OS knows to
> use that region. Otherwise PCIe devices would not work properly.
>
> Allow the memory-region property with one item pointing to a
> restricted DMA buffer.
>
> Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
> ---
> This patch compliments another patch that moved the memory-region from
> the PCIe device to the PCIe controller [1].
>
> [1] https://lore.kernel.org/all/20260430120725.241779-1-wenst@chromium.org/
>
> Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml | 4 ++++
> 1 file changed, 4 insertions(+)
>
Acked-by: Rob Herring (Arm) <robh@kernel.org>
^ permalink raw reply
* [PATCH 11/11] arm64: dts: renesas: r9a08g046l48-smarc: Add USB2.0 support
From: Biju @ 2026-06-12 14:30 UTC (permalink / raw)
To: Geert Uytterhoeven, Magnus Damm, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: Biju Das, linux-renesas-soc, devicetree, linux-kernel,
Prabhakar Mahadev Lad, Biju Das
In-Reply-To: <20260612143048.317907-1-biju.das.jz@bp.renesas.com>
From: Biju Das <biju.das.jz@bp.renesas.com>
Enable USB2.0 on the RZ/G3L SMARC board (r9a08g046l48-smarc):
- ehci0/ohci0: USB port 0 configured as OTG
- ehci1/ohci1: USB port 1 configured as host only
- phyrst: Enable the USB PHY reset controller
- usb2_phy0: Port 0 PHY with usb0_pins pinmux and usb0_vbus_otg supply
- usb2_phy1: Port 1 PHY with usb1_pins pinmux usb1_vbus_otg supply,
and renesas,no-otg-pins flag
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
.../boot/dts/renesas/r9a08g046l48-smarc.dts | 49 +++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/arch/arm64/boot/dts/renesas/r9a08g046l48-smarc.dts b/arch/arm64/boot/dts/renesas/r9a08g046l48-smarc.dts
index 96cc7ee46a6a..b189ae8e808d 100644
--- a/arch/arm64/boot/dts/renesas/r9a08g046l48-smarc.dts
+++ b/arch/arm64/boot/dts/renesas/r9a08g046l48-smarc.dts
@@ -87,6 +87,16 @@ vqmmc_sd1_pvdd: regulator-vqmmc-sd1-pvdd {
#endif
};
+&ehci0 {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&ehci1 {
+ dr_mode = "host";
+ status = "okay";
+};
+
&i2c2 {
pinctrl-0 = <&i2c2_pins>;
pinctrl-names = "default";
@@ -138,6 +148,20 @@ &keys {
#endif
};
+&ohci0 {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&ohci1 {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&phyrst {
+ status = "okay";
+};
+
&pinctrl {
audio_clk_pins: audio-clock {
pinmux = <RZG3L_PORT_PINMUX(H, 4, 6)>, /* AUDIO_CLK_B */
@@ -259,6 +283,16 @@ ssi0_pins: ssi0 {
<RZG3L_PORT_PINMUX(H, 2, 9)>, /* SSIF0_RCK */
<RZG3L_PORT_PINMUX(H, 3, 9)>; /* SSIF0_TXD */
};
+
+ usb0_pins: usb0 {
+ pinmux = <RZG3L_PORT_PINMUX(3, 0, 12)>, /* USB20_OVRCUR */
+ <RZG3L_PORT_PINMUX(3, 1, 12)>; /* USB20_VBUSEN */
+ };
+
+ usb1_pins: usb1 {
+ pinmux = <RZG3L_PORT_PINMUX(3, 4, 12)>, /* USB21_OVRCUR */
+ <RZG3L_PORT_PINMUX(3, 5, 12)>; /* USB21_VBUSEN */
+ };
};
#if SW_SER0_PMOD
@@ -330,3 +364,18 @@ &ssi0 {
status = "okay";
};
#endif
+
+&usb2_phy0 {
+ pinctrl-0 = <&usb0_pins>;
+ pinctrl-names = "default";
+ vbus-supply = <&usb0_vbus_otg>;
+ status = "okay";
+};
+
+&usb2_phy1 {
+ pinctrl-0 = <&usb1_pins>;
+ pinctrl-names = "default";
+ vbus-supply = <&usb1_vbus_otg>;
+ renesas,no-otg-pins;
+ status = "okay";
+};
--
2.43.0
^ permalink raw reply related
* [PATCH 10/11] arm64: dts: renesas: r9a08g046: Add USB2.0 device nodes
From: Biju @ 2026-06-12 14:30 UTC (permalink / raw)
To: Geert Uytterhoeven, Magnus Damm, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: Biju Das, linux-renesas-soc, devicetree, linux-kernel,
Prabhakar Mahadev Lad, Biju Das
In-Reply-To: <20260612143048.317907-1-biju.das.jz@bp.renesas.com>
From: Biju Das <biju.das.jz@bp.renesas.com>
Add USB2.0 device nodes to the RZ/G3L (r9a08g046) SoC DTSI.
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
arch/arm64/boot/dts/renesas/r9a08g046.dtsi | 103 +++++++++++++++++++++
1 file changed, 103 insertions(+)
diff --git a/arch/arm64/boot/dts/renesas/r9a08g046.dtsi b/arch/arm64/boot/dts/renesas/r9a08g046.dtsi
index 85e409ac8d5c..45aa41467e08 100644
--- a/arch/arm64/boot/dts/renesas/r9a08g046.dtsi
+++ b/arch/arm64/boot/dts/renesas/r9a08g046.dtsi
@@ -1198,6 +1198,109 @@ queue3 {
};
};
+ phyrst: usbphy-ctrl@11e00000 {
+ compatible = "renesas,r9a08g046-usbphy-ctrl";
+ reg = <0 0x11e00000 0 0x10000>;
+ clocks = <&cpg CPG_MOD R9A08G046_USB_PCLK>;
+ resets = <&cpg R9A08G046_USB_PRESETN>;
+ power-domains = <&cpg>;
+ #reset-cells = <1>;
+ renesas,sysc-pwrrdy = <&sysc 0xd70 0x1>;
+ status = "disabled";
+
+ usb0_vbus_otg: regulator-vbus {
+ regulator-name = "vbus0";
+ };
+
+ usb1_vbus_otg: regulator1-vbus {
+ regulator-name = "vbus1";
+ };
+ };
+
+ ohci0: usb@11e10000 {
+ compatible = "generic-ohci";
+ reg = <0 0x11e10000 0 0x100>;
+ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD R9A08G046_USB_PCLK>,
+ <&cpg CPG_MOD R9A08G046_USB_U2H0_HCLK>;
+ resets = <&phyrst 0>,
+ <&cpg R9A08G046_USB_U2H0_HRESETN>;
+ phys = <&usb2_phy0 1>;
+ phy-names = "usb";
+ power-domains = <&cpg>;
+ status = "disabled";
+ };
+
+ ohci1: usb@11e90000 {
+ compatible = "generic-ohci";
+ reg = <0 0x11e90000 0 0x100>;
+ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD R9A08G046_USB_PCLK>,
+ <&cpg CPG_MOD R9A08G046_USB_U2H1_HCLK>;
+ resets = <&phyrst 1>,
+ <&cpg R9A08G046_USB_U2H1_HRESETN>;
+ phys = <&usb2_phy1 1>;
+ phy-names = "usb";
+ power-domains = <&cpg>;
+ status = "disabled";
+ };
+
+ ehci0: usb@11e10100 {
+ compatible = "generic-ehci";
+ reg = <0 0x11e10100 0 0x100>;
+ interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD R9A08G046_USB_PCLK>,
+ <&cpg CPG_MOD R9A08G046_USB_U2H0_HCLK>;
+ resets = <&phyrst 0>,
+ <&cpg R9A08G046_USB_U2H0_HRESETN>;
+ phys = <&usb2_phy0 2>;
+ phy-names = "usb";
+ companion = <&ohci0>;
+ power-domains = <&cpg>;
+ status = "disabled";
+ };
+
+ ehci1: usb@11e90100 {
+ compatible = "generic-ehci";
+ reg = <0 0x11e90100 0 0x100>;
+ interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD R9A08G046_USB_PCLK>,
+ <&cpg CPG_MOD R9A08G046_USB_U2H1_HCLK>;
+ resets = <&phyrst 1>,
+ <&cpg R9A08G046_USB_U2H1_HRESETN>;
+ phys = <&usb2_phy1 2>;
+ phy-names = "usb";
+ companion = <&ohci1>;
+ power-domains = <&cpg>;
+ status = "disabled";
+ };
+
+ usb2_phy0: usb-phy@11e10200 {
+ compatible = "renesas,usb2-phy-r9a08g046";
+ reg = <0 0x11e10200 0 0x700>;
+ interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD R9A08G046_USB_PCLK>,
+ <&cpg CPG_MOD R9A08G046_USB_U2H0_HCLK>;
+ resets = <&phyrst 0>,
+ <&cpg R9A08G046_USB_U2H0_HRESETN>;
+ #phy-cells = <1>;
+ power-domains = <&cpg>;
+ status = "disabled";
+ };
+
+ usb2_phy1: usb-phy@11e90200 {
+ compatible = "renesas,usb2-phy-r9a08g046";
+ reg = <0 0x11e90200 0 0x700>;
+ interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD R9A08G046_USB_PCLK>,
+ <&cpg CPG_MOD R9A08G046_USB_U2H1_HCLK>;
+ resets = <&phyrst 1>,
+ <&cpg R9A08G046_USB_U2H1_HRESETN>;
+ #phy-cells = <1>;
+ power-domains = <&cpg>;
+ status = "disabled";
+ };
+
pcie: pcie@11e40000 {
reg = <0 0x11e40000 0 0x10000>;
ranges = <0x02000000 0 0x30000000 0 0x30000000 0 0x08000000>;
--
2.43.0
^ permalink raw reply related
* [PATCH 02/11] dt-bindings: phy: renesas,usb2-phy: Document RZ/G3L PHY bindings
From: Biju @ 2026-06-12 14:30 UTC (permalink / raw)
To: Vinod Koul, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm
Cc: Biju Das, Neil Armstrong, Yoshihiro Shimoda, linux-phy,
devicetree, linux-kernel, linux-renesas-soc,
Prabhakar Mahadev Lad, Biju Das
In-Reply-To: <20260612143048.317907-1-biju.das.jz@bp.renesas.com>
From: Biju Das <biju.das.jz@bp.renesas.com>
Add device tree binding support for the RZ/G3L (r9a08g046) USB2 PHY.
The RZ/G3L USB PHY is almost identical to the RZ/G3S USB PHY, the
difference being 2 OTG blocks on RZ/G3L compared to 1 on RZ/G3S.
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml b/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
index 9740e5b335f9..d6b9d08ceec6 100644
--- a/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
@@ -16,6 +16,7 @@ properties:
- enum:
- renesas,usb2-phy-r8a77470 # RZ/G1C
- renesas,usb2-phy-r9a08g045 # RZ/G3S
+ - renesas,usb2-phy-r9a08g046 # RZ/G3L
- renesas,usb2-phy-r9a09g057 # RZ/V2H(P)
- items:
@@ -132,6 +133,7 @@ allOf:
enum:
- renesas,usb2-phy-r9a09g057
- renesas,usb2-phy-r9a08g045
+ - renesas,usb2-phy-r9a08g046
- renesas,rzg2l-usb2-phy
then:
properties:
--
2.43.0
^ permalink raw reply related
* [PATCH 01/11] dt-bindings: reset: renesas,rzg2l-usbphy-ctrl: Document RZ/G3L support
From: Biju @ 2026-06-12 14:30 UTC (permalink / raw)
To: Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm
Cc: Biju Das, devicetree, linux-kernel, linux-renesas-soc,
Prabhakar Mahadev Lad, Biju Das
In-Reply-To: <20260612143048.317907-1-biju.das.jz@bp.renesas.com>
From: Biju Das <biju.das.jz@bp.renesas.com>
Add device tree binding support for the RZ/G3L (r9a08g046) USB PHY
controller. The RZ/G3L USB PHY block is similar to RZ/G3S, but each port
has an OTG controller, unlike RZ/G3S, which has an OTG controller only on
port 1.
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
.../reset/renesas,rzg2l-usbphy-ctrl.yaml | 20 ++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml b/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml
index c83469a1b379..788e467b38db 100644
--- a/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml
+++ b/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml
@@ -23,6 +23,7 @@ properties:
- renesas,r9a07g054-usbphy-ctrl # RZ/V2L
- const: renesas,rzg2l-usbphy-ctrl
- const: renesas,r9a08g045-usbphy-ctrl # RZ/G3S
+ - const: renesas,r9a08g046-usbphy-ctrl # RZ/G3L
reg:
maxItems: 1
@@ -50,6 +51,12 @@ properties:
$ref: /schemas/regulator/regulator.yaml#
unevaluatedProperties: false
+ regulator1-vbus:
+ type: object
+ description: Port 2 USB VBUS regulator
+ $ref: /schemas/regulator/regulator.yaml#
+ unevaluatedProperties: false
+
renesas,sysc-pwrrdy:
description:
The system controller PWRRDY indicates to the USB PHY if the power supply
@@ -78,7 +85,9 @@ allOf:
properties:
compatible:
contains:
- const: renesas,r9a08g045-usbphy-ctrl
+ enum:
+ - renesas,r9a08g045-usbphy-ctrl
+ - renesas,r9a08g046-usbphy-ctrl
then:
required:
- renesas,sysc-pwrrdy
@@ -86,6 +95,15 @@ allOf:
properties:
renesas,sysc-pwrrdy: false
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: renesas,r9a08g046-usbphy-ctrl
+ then:
+ required:
+ - regulator1-vbus
+
additionalProperties: false
examples:
--
2.43.0
^ permalink raw reply related
* [PATCH 00/11] Add RZ/G3L USB2.0 host support
From: Biju @ 2026-06-12 14:30 UTC (permalink / raw)
To: Philipp Zabel, Vinod Koul, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Geert Uytterhoeven, Michael Turquette, Stephen Boyd,
Liam Girdwood, Mark Brown, Magnus Damm
Cc: Biju Das, Neil Armstrong, Yoshihiro Shimoda, linux-phy,
devicetree, linux-kernel, linux-clk, linux-renesas-soc,
Prabhakar Mahadev Lad, Biju Das
From: Biju Das <biju.das.jz@bp.renesas.com>
Add device tree binding support for the RZ/G3L (r9a08g046) USB PHY
controller. The RZ/G3L USB PHY block is similar to RZ/G3S, but each port
has an OTG controller, unlike RZ/G3S, which has an OTG controller only on
port 1.
Biju Das (11):
dt-bindings: reset: renesas,rzg2l-usbphy-ctrl: Document RZ/G3L support
dt-bindings: phy: renesas,usb2-phy: Document RZ/G3L PHY bindings
clk: renesas: r9a08g046: Add USB2.0 clock and reset entries
reset: rzg2l-usbphy-ctrl: Introduce info struct for match data
reset: rzg2l-usbphy-ctrl: Add RZ/G3L support
regulator: renesas-usb-vbus-regulator: Introduce helper for regulator
registration
regulator: renesas-usb-vbus-regulator: Add RZ/G3L VBUS regulator
support
phy: renesas: phy-rcar-gen3-usb2: Add RZ/G3L support
phy: renesas: phy-rcar-gen3-usb2: Fix devm action registration for
disabled VBUS regulator
arm64: dts: renesas: r9a08g046: Add USB2.0 device nodes
arm64: dts: renesas: r9a08g046l48-smarc: Add USB2.0 support
.../bindings/phy/renesas,usb2-phy.yaml | 2 +
.../reset/renesas,rzg2l-usbphy-ctrl.yaml | 20 +++-
arch/arm64/boot/dts/renesas/r9a08g046.dtsi | 103 ++++++++++++++++++
.../boot/dts/renesas/r9a08g046l48-smarc.dts | 49 +++++++++
drivers/clk/renesas/r9a08g046-cpg.c | 15 +++
drivers/phy/renesas/phy-rcar-gen3-usb2.c | 20 ++--
.../regulator/renesas-usb-vbus-regulator.c | 72 ++++++++++--
drivers/reset/reset-rzg2l-usbphy-ctrl.c | 44 +++++---
8 files changed, 291 insertions(+), 34 deletions(-)
--
2.43.0
^ permalink raw reply
* Re: [PATCH v5 2/3] pwm: rp1: Add RP1 PWM controller driver
From: Sean Young @ 2026-06-12 14:29 UTC (permalink / raw)
To: Andrea della Porta
Cc: Uwe Kleine-König, linux-pwm, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
Broadcom internal kernel review list, devicetree,
linux-rpi-kernel, linux-arm-kernel, linux-kernel, Naushir Patuck,
Stanimir Varbanov, mbrugger
In-Reply-To: <f8dd46a553351adaf9d29fbba9f98e803b672fe7.1780670224.git.andrea.porta@suse.com>
On Fri, Jun 12, 2026 at 04:01:27PM +0200, Andrea della Porta wrote:
> From: Naushir Patuck <naush@raspberrypi.com>
>
> The Raspberry Pi RP1 southbridge features an embedded PWM
> controller with 4 output channels, alongside an RPM interface
> to read the fan speed on the Raspberry Pi 5.
>
> Add the supporting driver.
>
> Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
> Co-developed-by: Stanimir Varbanov <svarbanov@suse.de>
> Signed-off-by: Stanimir Varbanov <svarbanov@suse.de>
> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> ---
> drivers/pwm/Kconfig | 9 +
> drivers/pwm/Makefile | 1 +
> drivers/pwm/pwm-rp1.c | 424 ++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 434 insertions(+)
> create mode 100644 drivers/pwm/pwm-rp1.c
>
> diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
> index 6f3147518376a..c3ddc0eb4774f 100644
> --- a/drivers/pwm/Kconfig
> +++ b/drivers/pwm/Kconfig
> @@ -625,6 +625,15 @@ config PWM_ROCKCHIP
> Generic PWM framework driver for the PWM controller found on
> Rockchip SoCs.
>
> +config PWM_RASPBERRYPI_RP1
> + tristate "RP1 PWM support"
> + depends on MISC_RP1 || COMPILE_TEST
> + depends on HAS_IOMEM
> + select REGMAP_MMIO
> + select MFD_SYSCON
> + help
> + PWM framework driver for Raspberry Pi RP1 controller.
> +
> config PWM_SAMSUNG
> tristate "Samsung PWM support"
> depends on PLAT_SAMSUNG || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
> diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
> index 0dc0d2b69025d..59f29f60f9123 100644
> --- a/drivers/pwm/Makefile
> +++ b/drivers/pwm/Makefile
> @@ -56,6 +56,7 @@ obj-$(CONFIG_PWM_RENESAS_RZG2L_GPT) += pwm-rzg2l-gpt.o
> obj-$(CONFIG_PWM_RENESAS_RZ_MTU3) += pwm-rz-mtu3.o
> obj-$(CONFIG_PWM_RENESAS_TPU) += pwm-renesas-tpu.o
> obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o
> +obj-$(CONFIG_PWM_RASPBERRYPI_RP1) += pwm-rp1.o
> obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o
> obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o
> obj-$(CONFIG_PWM_SL28CPLD) += pwm-sl28cpld.o
> diff --git a/drivers/pwm/pwm-rp1.c b/drivers/pwm/pwm-rp1.c
> new file mode 100644
> index 0000000000000..6382a81a5ea0f
> --- /dev/null
> +++ b/drivers/pwm/pwm-rp1.c
> @@ -0,0 +1,424 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * pwm-rp1.c
> + *
> + * Raspberry Pi RP1 PWM.
> + *
> + * Copyright © 2026 Raspberry Pi Ltd.
> + *
> + * Author: Naushir Patuck (naush@raspberrypi.com)
> + *
> + * Based on the pwm-bcm2835 driver by:
> + * Bart Tanghe <bart.tanghe@thomasmore.be>
> + *
> + * Datasheet: https://pip-assets.raspberrypi.com/categories/892-raspberry-pi-5/documents/RP-008370-DS-1-rp1-peripherals.pdf?disposition=inline
> + *
> + * Limitations:
> + * - Channels can be enabled/disabled through a global update flag, while the
> + * period and duty per-channel registers are independently updatable, and
> + * they are latched on the end of (specific channel) period strobe.
> + * This means that period and duty changes might result in glitches if the
> + * period/duty is changed exactly during an end of period strobe.
> + * - Since the duty/period registers are freely updatable (do not depend on
> + * the global update flag), setting one of them close to the period end and
> + * the other right afterwards results in a mixed output for that cycle because
> + * the write ops are not atomic.
> + * - The global update flag prevents mis-sampling of multi-bit bus signals in
> + * the PWM clock domain. This ensures that all PWM channel settings update
> + * on the same PWM clock cycle. Channels start in sync only if they share the
> + * same period.
> + * - If both duty and period are set to 0, the output is a constant low signal
> + * if polarity is normal or a constant high signal if polarity is inversed.
> + * - When disabled the output is driven to 0 if polarity is normal, or to 1
> + * if polarity is inversed.
> + * - Disabling the PWM stops the output immediately, without waiting for current
> + * period to complete first.
> + * - Channels are phase-capable, but on RPi5, the firmware can use a channel
> + * phase register to report the RPM of the fan connected to that PWM
> + * channel. As a result, phase control will be ignored for now.
> + */
> +
> +#include <linux/bitops.h>
> +#include <linux/clk.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/pwm.h>
> +#include <linux/regmap.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/units.h>
> +
> +#define RP1_PWM_GLB_CTRL 0x000
> +#define RP1_PWM_GLB_CTRL_CHANNEL_ENABLE(chan) BIT(chan)
> +#define RP1_PWM_GLB_CTRL_SET_UPDATE BIT(31)
> +
> +#define RP1_PWM_CHAN_CTRL(chan) (0x014 + ((chan) * 0x10))
> +#define RP1_PWM_CHAN_CTRL_POLARITY BIT(3)
> +#define RP1_PWM_CHAN_CTRL_FIFO_POP_MASK BIT(8)
> +#define RP1_PWM_CHAN_CTRL_MODE GENMASK(2, 0)
> +enum rp1_pwm_ctrl_mode {
> + RP1_PWM_CHAN_CTRL_MODE_ZERO,
> + RP1_PWM_CHAN_CTRL_MODE_TE_MS,
> + RP1_PWM_CHAN_CTRL_MODE_PC_MS,
> + RP1_PWM_CHAN_CTRL_MODE_PD_ENC,
> + RP1_PWM_CHAN_CTRL_MODE_MSB_SER,
> + RP1_PWM_CHAN_CTRL_MODE_PPM,
> + RP1_PWM_CHAN_CTRL_MODE_LE_MS,
> + RP1_PWM_CHAN_CTRL_MODE_LSB_SER,
> +};
> +
> +#define RP1_PWM_CHAN_CTRL_DEFAULT (RP1_PWM_CHAN_CTRL_FIFO_POP_MASK + \
> + FIELD_PREP(RP1_PWM_CHAN_CTRL_MODE, \
> + RP1_PWM_CHAN_CTRL_MODE_TE_MS))
> +
> +#define RP1_PWM_RANGE(chan) (0x018 + ((chan) * 0x10))
> +#define RP1_PWM_PHASE(chan) (0x01C + ((chan) * 0x10))
> +#define RP1_PWM_DUTY(chan) (0x020 + ((chan) * 0x10))
> +
> +#define RP1_PWM_NUM_PWMS 4
> +
> +struct rp1_pwm {
> + struct regmap *regmap;
> + struct clk *clk;
> + unsigned long clk_rate;
> + bool clk_enabled;
I don't understand the point of the clk_enabled field. If the probe
function succeeds, then clk_enabled = true. It is set to false during
suspend, but after suspend the only thing which can follow is resume,
I think. In resume, we set it in to true again unconditionally. So
it is always true, no?
> +};
> +
> +struct rp1_pwm_waveform {
> + u32 period_ticks;
> + u32 duty_ticks;
> + bool enabled;
> + bool inverted_polarity;
> +};
> +
> +static const struct regmap_config rp1_pwm_regmap_config = {
> + .reg_bits = 32,
> + .val_bits = 32,
> + .reg_stride = 4,
> + .max_register = 0x60,
> +};
> +
> +static void rp1_pwm_apply_config(struct pwm_chip *chip, struct pwm_device *pwm)
> +{
> + struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
> + u32 value;
> +
> + /* update the changed registers on the next strobe to avoid glitches */
> + regmap_read(rp1->regmap, RP1_PWM_GLB_CTRL, &value);
> + value |= RP1_PWM_GLB_CTRL_SET_UPDATE;
> + regmap_write(rp1->regmap, RP1_PWM_GLB_CTRL, value);
> +}
> +
> +static int rp1_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
> +{
> + struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
> +
> + /* init channel to reset defaults, preserving the polarity bit */
> + regmap_update_bits(rp1->regmap, RP1_PWM_CHAN_CTRL(pwm->hwpwm),
> + ~(u32)RP1_PWM_CHAN_CTRL_POLARITY, RP1_PWM_CHAN_CTRL_DEFAULT);
> + return 0;
> +}
> +
> +static int rp1_pwm_round_waveform_tohw(struct pwm_chip *chip,
> + struct pwm_device *pwm,
> + const struct pwm_waveform *wf,
> + void *_wfhw)
> +{
> + struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
> + u64 period_ticks, duty_ticks, offset_ticks;
> + struct rp1_pwm_waveform *wfhw = _wfhw;
> + u64 clk_rate = rp1->clk_rate;
> + int ret = 0;
> +
> + if (!wf->period_length_ns) {
> + wfhw->enabled = false;
> + return 0;
> + }
> +
> + period_ticks = mul_u64_u64_div_u64(wf->period_length_ns, clk_rate, NSEC_PER_SEC);
> +
> + /*
> + * The period is limited to U32_MAX, and it will be decremented by one later
> + * to allow 100% duty cycle.
> + */
> + if (period_ticks > U32_MAX) {
> + period_ticks = U32_MAX;
> + } else if (period_ticks < 2) {
> + period_ticks = 2;
> + ret = 1;
> + }
period_ticks = clamp(period_ticks, 2, U32_MAX);
Although that misses out the `ret = 1;` which I am not sure about anyway.
> +
> + duty_ticks = mul_u64_u64_div_u64(wf->duty_length_ns, clk_rate, NSEC_PER_SEC);
> + duty_ticks = min(duty_ticks, period_ticks);
> + offset_ticks = mul_u64_u64_div_u64(wf->duty_offset_ns, clk_rate, NSEC_PER_SEC);
> + if (offset_ticks >= period_ticks)
> + offset_ticks %= period_ticks;
> + if (duty_ticks && offset_ticks &&
> + duty_ticks + offset_ticks >= period_ticks) {
> + wfhw->duty_ticks = period_ticks - duty_ticks;
> + wfhw->inverted_polarity = true;
> + } else {
> + wfhw->duty_ticks = duty_ticks;
> + wfhw->inverted_polarity = false;
> + }
> + /* Account for the extra tick at the end of the period */
> + wfhw->period_ticks = period_ticks - 1;
> +
> + wfhw->enabled = true;
> +
> + return ret;
> +}
> +
> +static int rp1_pwm_round_waveform_fromhw(struct pwm_chip *chip,
> + struct pwm_device *pwm,
> + const void *_wfhw,
> + struct pwm_waveform *wf)
> +{
> + struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
> + const struct rp1_pwm_waveform *wfhw = _wfhw;
> + u64 clk_rate = rp1->clk_rate;
> + u64 ticks;
> +
> + *wf = (struct pwm_waveform){ };
> +
> + if (!wfhw->enabled)
> + return 0;
> +
> + wf->period_length_ns = DIV_ROUND_UP_ULL(((u64)wfhw->period_ticks + 1) * NSEC_PER_SEC,
> + clk_rate);
> +
> + if (!wfhw->inverted_polarity) {
> + wf->duty_length_ns = DIV_ROUND_UP_ULL((u64)wfhw->duty_ticks * NSEC_PER_SEC,
> + clk_rate);
> + } else {
> + ticks = (u64)wfhw->period_ticks + 1 - wfhw->duty_ticks;
> + wf->duty_length_ns = DIV_ROUND_UP_ULL(ticks * NSEC_PER_SEC, clk_rate);
> + wf->duty_offset_ns = wf->period_length_ns - wf->duty_length_ns;
> + }
> +
> + return 0;
> +}
> +
> +static int rp1_pwm_write_waveform(struct pwm_chip *chip,
> + struct pwm_device *pwm,
> + const void *_wfhw)
> +{
> + struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
> + const struct rp1_pwm_waveform *wfhw = _wfhw;
> + u32 value, ctrl;
> +
> + /* set polarity */
> + regmap_read(rp1->regmap, RP1_PWM_CHAN_CTRL(pwm->hwpwm), &value);
> + if (!wfhw->inverted_polarity)
> + value &= ~RP1_PWM_CHAN_CTRL_POLARITY;
> + else
> + value |= RP1_PWM_CHAN_CTRL_POLARITY;
> + regmap_write(rp1->regmap, RP1_PWM_CHAN_CTRL(pwm->hwpwm), value);
> +
> + /* early exit if disabled */
> + regmap_read(rp1->regmap, RP1_PWM_GLB_CTRL, &ctrl);
> + if (!wfhw->enabled) {
> + ctrl &= ~RP1_PWM_GLB_CTRL_CHANNEL_ENABLE(pwm->hwpwm);
> + goto exit_disable;
> + }
> +
> + /* set period and duty cycle */
> + regmap_write(rp1->regmap,
> + RP1_PWM_RANGE(pwm->hwpwm), wfhw->period_ticks);
> + regmap_write(rp1->regmap,
> + RP1_PWM_DUTY(pwm->hwpwm), wfhw->duty_ticks);
> +
> + /* enable the channel */
> + ctrl |= RP1_PWM_GLB_CTRL_CHANNEL_ENABLE(pwm->hwpwm);
> +exit_disable:
> + regmap_write(rp1->regmap, RP1_PWM_GLB_CTRL, ctrl);
> +
> + rp1_pwm_apply_config(chip, pwm);
> +
> + return 0;
> +}
> +
> +static int rp1_pwm_read_waveform(struct pwm_chip *chip,
> + struct pwm_device *pwm,
> + void *_wfhw)
> +{
> + struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
> + struct rp1_pwm_waveform *wfhw = _wfhw;
> + u32 value;
> +
> + regmap_read(rp1->regmap, RP1_PWM_GLB_CTRL, &value);
> + wfhw->enabled = !!(value & RP1_PWM_GLB_CTRL_CHANNEL_ENABLE(pwm->hwpwm));
> +
> + regmap_read(rp1->regmap, RP1_PWM_CHAN_CTRL(pwm->hwpwm), &value);
> + wfhw->inverted_polarity = !!(value & RP1_PWM_CHAN_CTRL_POLARITY);
> +
> + if (wfhw->enabled) {
> + regmap_read(rp1->regmap, RP1_PWM_RANGE(pwm->hwpwm), &wfhw->period_ticks);
> + regmap_read(rp1->regmap, RP1_PWM_DUTY(pwm->hwpwm), &wfhw->duty_ticks);
> + } else {
> + wfhw->period_ticks = 0;
> + wfhw->duty_ticks = 0;
> + }
> +
> + return 0;
> +}
> +
> +static const struct pwm_ops rp1_pwm_ops = {
> + .sizeof_wfhw = sizeof(struct rp1_pwm_waveform),
> + .request = rp1_pwm_request,
> + .round_waveform_tohw = rp1_pwm_round_waveform_tohw,
> + .round_waveform_fromhw = rp1_pwm_round_waveform_fromhw,
> + .read_waveform = rp1_pwm_read_waveform,
> + .write_waveform = rp1_pwm_write_waveform,
> +};
> +
> +static int rp1_pwm_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct device_node *np = dev->of_node;
> + unsigned long clk_rate;
> + struct pwm_chip *chip;
> + void __iomem *base;
> + struct rp1_pwm *rp1;
> + int ret;
> +
> + chip = devm_pwmchip_alloc(dev, RP1_PWM_NUM_PWMS, sizeof(*rp1));
> + if (IS_ERR(chip))
> + return PTR_ERR(chip);
> +
> + rp1 = pwmchip_get_drvdata(chip);
> +
> + base = devm_platform_ioremap_resource(pdev, 0);
> + if (IS_ERR(base))
> + return PTR_ERR(base);
> +
> + rp1->regmap = devm_regmap_init_mmio(dev, base, &rp1_pwm_regmap_config);
> + if (IS_ERR(rp1->regmap))
> + return dev_err_probe(dev, PTR_ERR(rp1->regmap), "Cannot initialize regmap\n");
> +
> + rp1->clk = devm_clk_get(dev, NULL);
> + if (IS_ERR(rp1->clk))
> + return dev_err_probe(dev, PTR_ERR(rp1->clk), "Clock not found\n");
> +
> + ret = clk_prepare_enable(rp1->clk);
> + if (ret)
> + return dev_err_probe(dev, ret, "Failed to enable clock\n");
> + rp1->clk_enabled = true;
> +
> + ret = devm_clk_rate_exclusive_get(dev, rp1->clk);
> + if (ret) {
> + dev_err_probe(dev, ret, "Failed to get exclusive rate\n");
> + goto err_disable_clk;
> + }
> +
> + clk_rate = clk_get_rate(rp1->clk);
> + if (!clk_rate) {
> + ret = dev_err_probe(dev, -EINVAL, "Failed to get clock rate\n");
> + goto err_disable_clk;
> + }
> + /*
> + * To prevent u64 overflow in period calculations:
> + * mul_u64_u64_div_u64(period_ns, clk_rate, NSEC_PER_SEC)
> + * If clk_rate > 1 GHz, the result can overflow.
> + */
> + if (clk_rate > HZ_PER_GHZ) {
> + ret = dev_err_probe(dev, -EINVAL, "Clock rate > 1 GHz is not supported\n");
> + goto err_disable_clk;
> + }
> + rp1->clk_rate = clk_rate;
> +
> + chip->ops = &rp1_pwm_ops;
Can we add the following please:
chip->atomic = true;
This means that the pwm can be controlled from atomic context (not process
context) using pwm_apply_atomic(). This is very helpful for the pwm-ir-tx
driver, which produces a much more faithful IR signal in atomic context.
Using pwm for infrared tx is much nicer than using gpio which bit bangs
the IR signal and holds the CPU with interrupts disabled for upto one second.
As far as I can see there is no sleeping code in these code paths, so we
should be fine.
Thanks,
Sean
> +
> + platform_set_drvdata(pdev, chip);
> +
> + ret = pwmchip_add(chip);
> + if (ret) {
> + dev_err_probe(dev, ret, "Failed to register PWM chip\n");
> + goto err_disable_clk;
> + }
> +
> + ret = of_syscon_register_regmap(np, rp1->regmap);
> + if (ret) {
> + dev_err_probe(dev, ret, "Failed to register syscon\n");
> + goto err_remove_chip;
> + }
> +
> + return 0;
> +
> +err_remove_chip:
> + pwmchip_remove(chip);
> +err_disable_clk:
> + clk_disable_unprepare(rp1->clk);
> +
> + return ret;
> +}
> +
> +static void rp1_pwm_remove(struct platform_device *pdev)
> +{
> + struct pwm_chip *chip = platform_get_drvdata(pdev);
> + struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
> +
> + pwmchip_remove(chip);
> +
> + if (rp1->clk_enabled) {
> + clk_disable_unprepare(rp1->clk);
> + rp1->clk_enabled = false;
> + }
> +}
> +
> +static int rp1_pwm_suspend(struct device *dev)
> +{
> + struct pwm_chip *chip = dev_get_drvdata(dev);
> + struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
> +
> + if (rp1->clk_enabled) {
> + clk_disable_unprepare(rp1->clk);
> + rp1->clk_enabled = false;
> + }
> +
> + return 0;
> +}
> +
> +static int rp1_pwm_resume(struct device *dev)
> +{
> + struct pwm_chip *chip = dev_get_drvdata(dev);
> + struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
> + int ret;
> +
> + ret = clk_prepare_enable(rp1->clk);
> + if (ret) {
> + dev_err(dev, "Failed to enable clock on resume: %pe\n", ERR_PTR(ret));
> + return ret;
> + }
> +
> + rp1->clk_enabled = true;
> +
> + return 0;
> +}
> +
> +static DEFINE_SIMPLE_DEV_PM_OPS(rp1_pwm_pm_ops, rp1_pwm_suspend, rp1_pwm_resume);
> +
> +static const struct of_device_id rp1_pwm_of_match[] = {
> + { .compatible = "raspberrypi,rp1-pwm" },
> + { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, rp1_pwm_of_match);
> +
> +static struct platform_driver rp1_pwm_driver = {
> + .probe = rp1_pwm_probe,
> + .remove = rp1_pwm_remove,
> + .driver = {
> + .name = "rp1-pwm",
> + .of_match_table = rp1_pwm_of_match,
> + .pm = pm_ptr(&rp1_pwm_pm_ops),
> + .suppress_bind_attrs = true,
> + },
> +};
> +builtin_platform_driver(rp1_pwm_driver);
> +
> +MODULE_DESCRIPTION("RP1 PWM driver");
> +MODULE_AUTHOR("Naushir Patuck <naush@raspberrypi.com>");
> +MODULE_AUTHOR("Andrea della Porta <andrea.porta@suse.com>");
> +MODULE_LICENSE("GPL");
> --
> 2.35.3
>
^ permalink raw reply
* Re: [PATCH v2 1/3] misc: lis3lv02d: set default click detection thresholds
From: Linus Walleij @ 2026-06-12 14:21 UTC (permalink / raw)
To: Md Shofiqul Islam
Cc: linux-iio, devicetree, jic23, robh, krzk+dt, conor+dt,
linux-kernel
In-Reply-To: <20260611154105.3727-2-shofiqtest@gmail.com>
On Thu, Jun 11, 2026 at 5:41 PM Md Shofiqul Islam <shofiqtest@gmail.com> wrote:
> Several upstream board DTS files use st,click-thresh-x/y/z (the name
> documented in the old lis302.txt binding), but the driver reads
> st,click-threshold-x/y/z. As a result those boards have had click
> detection silently broken since the DT properties were added.
>
> Set a default threshold of 10 for all three axes immediately after
> the platform data allocation so those boards get working click
> detection without requiring a DT change.
>
> The DT reads for st,click-threshold-x/y/z are unchanged so boards
> using the correct name can still override the default.
>
> Fixes: 6a7740c7f5b2 ("lis3lv02d: add device-tree support")
>
> Signed-off-by: Md Shofiqul Islam <shofiqtest@gmail.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH v3 3/3] media: i2c: os02g10: implement crop handling with set_selection
From: Tarang Raval @ 2026-06-12 14:20 UTC (permalink / raw)
To: Vladimir Zapolskiy
Cc: Elgin Perumbilly, laurent.pinchart@ideasonboard.com,
sakari.ailus@linux.intel.com, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Hans Verkuil, Hans de Goede,
Mehdi Djait, Sylvain Petinot, Benjamin Mugnier,
Bryan O'Donoghue, Heimir Thor Sverrisson, Hardevsinh Palaniya,
linux-media@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <6f664514-34bf-44db-8df1-9b1a774e6367@linaro.org>
> On 6/12/26 14:41, Tarang Raval wrote:
> > Hi Vladimir,
> >
> > Thank you for the review.
> >
> > Since I authored this patch, I will try to address the comments below.
> >
> >> On 4/24/26 12:25, Elgin Perumbilly wrote:
> >>> From: Tarang Raval <tarang.raval@siliconsignals.io>
> >>>
> >>> Add crop support to os02g10 by implementing .set_selection() and
> >>> storing the crop rectangle in subdev state.
> >>>
> >>> Initialize the default crop to the active area, make set_fmt() use the
> >>> current crop, and update the output format when the crop size changes.
> >>> Also program the sensor window from the active crop/format state instead
> >>> of using the fixed supported_modes entry.
> >>>
> >>> This allows userspace to configure the sensor crop window explicitly.
> >>>
> >>> Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io>
> >>> Signed-off-by: Elgin Perumbilly <elgin.perumbilly@siliconsignals.io>
> >>> ---
> >>> drivers/media/i2c/os02g10.c | 166 ++++++++++++++++++++++--------------
> >>> 1 file changed, 103 insertions(+), 63 deletions(-)
> >>>
> >>> diff --git a/drivers/media/i2c/os02g10.c b/drivers/media/i2c/os02g10.c
> >>> index fad2dd0ad7aa..9bf8f5d1caea 100644
> >>> --- a/drivers/media/i2c/os02g10.c
> >>> +++ b/drivers/media/i2c/os02g10.c
> >>> @@ -112,6 +112,11 @@
> >>> #define OS02G10_ORIENTATION_BAYER_FIX 0x32
> >>>
> >>> #define OS02G10_LINK_FREQ_720MHZ (720 * HZ_PER_MHZ)
> >>> +#define OS02G10_WINDOW_WIDTH_MIN 2
> >>> +#define OS02G10_WINDOW_HEIGHT_MIN 2
> >>
> >> Add a blank line before the new group of macro.
> >>
> >>> +#define OS02G10_VBLANK_DEF 166
> >>
> >> This one is computable, and it can be dropped.
> >
> >
> > Can you explain how this value can be computed ?
>
> It is (supported_modes[0].vts_def - supported_modes[0].height) on
> the base of 2/3 change.
In this patch, the supported_modes structure has been removed, so the value
can no longer be computed in that way.
> >>> +#define OS02G10_VBLANK_MIN 25
> >>
> >> This macro shall be added to the group of OS02G10_REG_FRAME_LENGTH
> >> register, and it should be included into the previous change.
> >>
> >>> +#define OS02G10_EXPOSURE_DEF 1100
> >>
> >> This macro shall be added to the group of OS02G10_REG_LONG_EXPOSURE
> >> register, and it should be included into the previous change.
> >
> >
> > I would prefer to introduce these macros here only, as they are related to
> > this patch. There is no use of these macros in the previous patch, so moving
> > them there would not provide any benefit.
>
> Unavoidably there shall be a user of "default exposure" in the change 2/3, and
> therefore the value is present, please reference to supported_modes[0].exp_def.
>
> So, this macro goes to the 2/3 patch.
In patch 2/3, the supported_modes structure is still present, so I don't
think introducing a separate macro there provides much benefit.
Using:
vts_def = height + OS02G10_VBLANK_DEF;
exp_def = OS02G10_VBLANK_DEF;
doesn't look particularly readable to me either. However, I'd be interested
to hear your preference on this.
> >
> > I will group them in the appropriate place within this patch as per your
> > suggestion.
> >
> >
> >>>
> >>> /* OS02G10 native and active pixel array size */
> >>> static const struct v4l2_rect os02g10_native_area = {
> >>> @@ -152,15 +157,6 @@ struct os02g10 {
> >>> struct v4l2_ctrl *hflip;
> >>> };
> >>>
> >>> -struct os02g10_mode {
> >>> - u32 width;
> >>> - u32 height;
> >>> - u32 vts_def;
> >>> - u32 exp_def;
> >>> - u32 x_start;
> >>> - u32 y_start;
> >>> -};
> >>> -
> >>> static const struct cci_reg_sequence os02g10_common_regs[] = {
> >>> { OS02G10_REG_PLL_DIV_CTRL, 0x0a},
> >>> { OS02G10_REG_PLL_DCTL_BIAS_CTRL, 0x04},
> >
> > ...
> >
> >>> static const struct v4l2_subdev_video_ops os02g10_video_ops = {
> >>> @@ -645,6 +684,7 @@ static const struct v4l2_subdev_pad_ops os02g10_pad_ops = {
> >>> .get_fmt = v4l2_subdev_get_fmt,
> >>> .set_fmt = os02g10_set_pad_format,
> >>> .get_selection = os02g10_get_selection,
> >>> + .set_selection = os02g10_set_selection,
> >>> .enum_frame_size = os02g10_enum_frame_size,
> >>> .enable_streams = os02g10_enable_streams,
> >>> .disable_streams = os02g10_disable_streams,
> >>
> >> I understand that this change is written by another person, and likely
> >> it is not squashed with the previous one to preserve authorship, however
> >> it significantly rewrites the change already found in the series.
> >
> > I don't think this patch significantly rewrites the previous changes. Its
> > main purpose is to introduce a crop rectangle and implement set_selection(),
> > allowing userspace to stream arbitrary resolutions within the sensor limits
> > instead of being restricted to 1920x1080.
>
> What are these "sensor limits" number? Are they defined in this 3/3 change?
> For whatever reason I can't find it, but I may be blind.
The sensor limits are defined by os02g10_active_area and enforced in
os02g10_set_selection(). The crop rectangle cannot extend beyond the
active sensor area, and the minimum crop size is also constrained in
the same function.
+ rect.width = clamp_t(unsigned int, ALIGN(sel->r.width, 2),
+ OS02G10_WINDOW_WIDTH_MIN,
+ os02g10_active_area.width);
+ rect.height = clamp_t(unsigned int, ALIGN(sel->r.height, 2),
+ OS02G10_WINDOW_HEIGHT_MIN,
+ os02g10_active_area.height);
> >> I don't see information about the maximum supported frame height/width
> >> or default VTS setting etc. anymore, for me it's hard to say, if
> >> this kind of information can be dropped with no consequences in runtime.
> >
> > The maximum supported width and height are still defined and enforced in
> > os02g10_set_selection(). The default VTS handling is implemented in
> > os02g10_set_pad_format(), where VBLANK is adjusted to maintain 30 fps for
> > the selected resolution. So I don't believe any information has been dropped.
> >
> >> Probably this 3/3 change will break a quick inclusion of the sensor
> >> driver, you may consider to exlcude it from the series now, and publish
> >> it afterwards.
> >
> > Regarding whether patch 3/3 should be included in the current series, I am
> > happy to leave that decision to Sakari. If needed, this patch can be merged
> > separately once the new raw sensor model is finalized.
> >
> > This patch was created based on Laurent's suggestion.
> >
> > Link: https://lore.kernel.org/linux-media/20260414084952.217215-1-elgin.perumbilly@siliconsignals.io/T/#t
> >
>
> That's a helpful reference to the previous patch review, thank you.
> Likely I don't have the whole picture of the new advances in linux-media.
No worries, and thank you for taking the time to review the series and
provide feedback.
Best Regards,
Tarang
^ permalink raw reply
* Re: [PATCH v2 3/3] dt-bindings: iio: accel: convert lis302 binding to YAML schema (v2)
From: Linus Walleij @ 2026-06-12 14:16 UTC (permalink / raw)
To: Md Shofiqul Islam
Cc: linux-iio, devicetree, jic23, robh, krzk+dt, conor+dt,
linux-kernel
In-Reply-To: <20260611154105.3727-4-shofiqtest@gmail.com>
Hi Shofiqul,
thanks for your patch! And thanks for working with the ST MEMS sensors!
On Thu, Jun 11, 2026 at 5:41 PM Md Shofiqul Islam <shofiqtest@gmail.com> wrote:
> Replace the plain text lis302.txt with a YAML schema for the
> LIS302DL/LIS3LV02D accelerometer family.
(...)
> +maintainers:
> + - Linus Walleij <linus.walleij@linaro.org>
Please use my new email address:
Linus Walleij <linusw@kernel.org>
I don't mind being listed as maintainer, ideally I think someone at ST
should pick this up but I have good relationship with them so this
is fine unless someone signs up for the job.
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH v5 2/3] pwm: rp1: Add RP1 PWM controller driver
From: sashiko-bot @ 2026-06-12 14:13 UTC (permalink / raw)
To: Andrea della Porta; +Cc: devicetree, conor+dt, robh
In-Reply-To: <f8dd46a553351adaf9d29fbba9f98e803b672fe7.1780670224.git.andrea.porta@suse.com>
Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
- [High] Registering a devm-managed regmap with the syscon subsystem leads to a Use-After-Free.
- [High] The `wfhw->inverted_polarity` field is left uninitialized when disabling the PWM channel, leading to random inactive pin states.
- [Medium] Underflow in duty cycle calculation when hardware DUTY register exceeds RANGE + 1.
- [Medium] Non-atomic read-modify-write sequences on shared global registers race with syscon consumers.
- [Medium] Hardware configuration registers are not restored during system resume.
- [Low] 64-bit modulo and division operations cause link errors on 32-bit platforms.
--
commit b70ebe40d042bfe1fa3353e46fc0881fdfa5686f
Author: Naushir Patuck <naush@raspberrypi.com>
pwm: rp1: Add RP1 PWM controller driver
The Raspberry Pi RP1 southbridge features an embedded PWM
controller with 4 output channels, alongside an RPM interface
to read the fan speed on the Raspberry Pi 5.
> diff --git a/drivers/pwm/pwm-rp1.c b/drivers/pwm/pwm-rp1.c
> new file mode 100644
> index 0000000000000..6382a81a5ea0f
> --- /dev/null
> +++ b/drivers/pwm/pwm-rp1.c
[ ... ]
> +static void rp1_pwm_apply_config(struct pwm_chip *chip, struct pwm_device *pwm)
> +{
> + struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
> + u32 value;
> +
> + /* update the changed registers on the next strobe to avoid glitches */
> + regmap_read(rp1->regmap, RP1_PWM_GLB_CTRL, &value);
> + value |= RP1_PWM_GLB_CTRL_SET_UPDATE;
> + regmap_write(rp1->regmap, RP1_PWM_GLB_CTRL, value);
> +}
[Severity: Medium]
Will this read-modify-write sequence race with syscon consumers?
Since this driver exposes its regmap via syscon to allow other drivers to
access it concurrently, a separate regmap_read() and regmap_write()
releases the internal lock in between.
If a syscon consumer modifies RP1_PWM_GLB_CTRL simultaneously, will its
changes be silently overwritten? Should this use regmap_update_bits()
instead?
[ ... ]
> +static int rp1_pwm_round_waveform_tohw(struct pwm_chip *chip,
> + struct pwm_device *pwm,
> + const struct pwm_waveform *wf,
> + void *_wfhw)
> +{
> + struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
> + u64 period_ticks, duty_ticks, offset_ticks;
> + struct rp1_pwm_waveform *wfhw = _wfhw;
> + u64 clk_rate = rp1->clk_rate;
> + int ret = 0;
> +
> + if (!wf->period_length_ns) {
> + wfhw->enabled = false;
> + return 0;
> + }
[Severity: High]
Does this early return leave wfhw->inverted_polarity uninitialized?
If the PWM core passes uninitialized memory for _wfhw, returning here
without setting inverted_polarity means rp1_pwm_write_waveform() will later
read uninitialized memory to configure the RP1_PWM_CHAN_CTRL_POLARITY bit.
Because the hardware drives the pin to 0 or 1 based on polarity when disabled,
could this cause the disabled state to unpredictably flip between high and low?
[ ... ]
> + duty_ticks = mul_u64_u64_div_u64(wf->duty_length_ns, clk_rate, NSEC_PER_SEC);
> + duty_ticks = min(duty_ticks, period_ticks);
> + offset_ticks = mul_u64_u64_div_u64(wf->duty_offset_ns, clk_rate, NSEC_PER_SEC);
> + if (offset_ticks >= period_ticks)
> + offset_ticks %= period_ticks;
[Severity: Low]
Will this 64-bit modulo operation cause link errors on 32-bit builds?
Since both offset_ticks and period_ticks are u64, using the modulo
operator directly will emit a call to __umoddi3. Since Kconfig allows
COMPILE_TEST, will this break the build on 32-bit architectures?
[ ... ]
> +static int rp1_pwm_round_waveform_fromhw(struct pwm_chip *chip,
> + struct pwm_device *pwm,
> + const void *_wfhw,
> + struct pwm_waveform *wf)
> +{
> + struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
> + const struct rp1_pwm_waveform *wfhw = _wfhw;
> + u64 clk_rate = rp1->clk_rate;
> + u64 ticks;
> +
> + *wf = (struct pwm_waveform){ };
> +
> + if (!wfhw->enabled)
> + return 0;
> +
> + wf->period_length_ns = DIV_ROUND_UP_ULL(((u64)wfhw->period_ticks + 1) * NSEC_PER_SEC,
> + clk_rate);
> +
> + if (!wfhw->inverted_polarity) {
> + wf->duty_length_ns = DIV_ROUND_UP_ULL((u64)wfhw->duty_ticks * NSEC_PER_SEC,
> + clk_rate);
[Severity: Low]
Is it safe to pass clk_rate as a u64 divisor to DIV_ROUND_UP_ULL()?
DIV_ROUND_UP_ULL uses do_div() internally which expects a 32-bit divisor.
Will this cause division helpers to be missing during 32-bit builds?
> + } else {
> + ticks = (u64)wfhw->period_ticks + 1 - wfhw->duty_ticks;
[Severity: Medium]
Can this calculation underflow if the hardware DUTY register exceeds RANGE + 1?
rp1_pwm_read_waveform() fetches period_ticks and duty_ticks directly from
the hardware registers without clamping. If the bootloader configures a
duty cycle greater than the period (to force a continuous 100% output),
would this undergo an unsigned underflow?
Could this result in an astronomically large u64 value for ticks, corrupting
the reported duty_length_ns?
> + wf->duty_length_ns = DIV_ROUND_UP_ULL(ticks * NSEC_PER_SEC, clk_rate);
> + wf->duty_offset_ns = wf->period_length_ns - wf->duty_length_ns;
> + }
> +
> + return 0;
> +}
> +
> +static int rp1_pwm_write_waveform(struct pwm_chip *chip,
> + struct pwm_device *pwm,
> + const void *_wfhw)
> +{
> + struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
> + const struct rp1_pwm_waveform *wfhw = _wfhw;
> + u32 value, ctrl;
> +
> + /* set polarity */
> + regmap_read(rp1->regmap, RP1_PWM_CHAN_CTRL(pwm->hwpwm), &value);
> + if (!wfhw->inverted_polarity)
> + value &= ~RP1_PWM_CHAN_CTRL_POLARITY;
> + else
> + value |= RP1_PWM_CHAN_CTRL_POLARITY;
> + regmap_write(rp1->regmap, RP1_PWM_CHAN_CTRL(pwm->hwpwm), value);
[Severity: Medium]
Is this another non-atomic read-modify-write susceptible to data races?
Similar to rp1_pwm_apply_config(), will syscon consumer modifications to
RP1_PWM_CHAN_CTRL be lost if they occur between the read and write?
[ ... ]
> +static int rp1_pwm_probe(struct platform_device *pdev)
> +{
[ ... ]
> + rp1->regmap = devm_regmap_init_mmio(dev, base, &rp1_pwm_regmap_config);
> + if (IS_ERR(rp1->regmap))
> + return dev_err_probe(dev, PTR_ERR(rp1->regmap), "Cannot initialize regmap\n");
[ ... ]
> + ret = of_syscon_register_regmap(np, rp1->regmap);
> + if (ret) {
> + dev_err_probe(dev, ret, "Failed to register syscon\n");
> + goto err_remove_chip;
> + }
> +
> + return 0;
> +
> +err_remove_chip:
> + pwmchip_remove(chip);
> +err_disable_clk:
> + clk_disable_unprepare(rp1->clk);
> +
> + return ret;
> +}
> +
> +static void rp1_pwm_remove(struct platform_device *pdev)
> +{
> + struct pwm_chip *chip = platform_get_drvdata(pdev);
> + struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
> +
> + pwmchip_remove(chip);
> +
> + if (rp1->clk_enabled) {
> + clk_disable_unprepare(rp1->clk);
> + rp1->clk_enabled = false;
> + }
> +}
[Severity: High]
Will registering a devm-managed regmap with the syscon subsystem lead to a
use-after-free on device unbind?
The syscon subsystem stores this regmap pointer in a global, permanent list
and provides no API to unregister it. If the RP1 device is unbound, devres
will automatically free the regmap memory.
Would any subsequent syscon lookup by consumers return this freed memory,
triggering a use-after-free?
[ ... ]
> +static int rp1_pwm_resume(struct device *dev)
> +{
> + struct pwm_chip *chip = dev_get_drvdata(dev);
> + struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
> + int ret;
> +
> + ret = clk_prepare_enable(rp1->clk);
> + if (ret) {
> + dev_err(dev, "Failed to enable clock on resume: %pe\n", ERR_PTR(ret));
> + return ret;
> + }
> +
> + rp1->clk_enabled = true;
> +
> + return 0;
> +}
[Severity: Medium]
Does the resume handler need to restore the hardware register state?
The PM operations only toggle the clock, but do not save and restore the
PWM configuration registers (such as RP1_PWM_GLB_CTRL, CHAN_CTRL, RANGE,
DUTY), and the regmap lacks a cache configuration to do this automatically.
If the hardware loses its state during S3 suspend, will the controller
wake up in its default reset state (stopped), breaking consumer devices
that expect the PWM signal to be maintained?
--
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1780670224.git.andrea.porta@suse.com?part=2
^ permalink raw reply
* Re: [PATCH] dt-bindings: cache: l2c2x0: Add missing power-domains
From: Rob Herring (Arm) @ 2026-06-12 14:11 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Conor Dooley, Krzysztof Kozlowski, devicetree, linux-renesas-soc,
Jonathan Cameron
In-Reply-To: <0a57ab356e5f426e28ead373b809f88a63e55380.1781105151.git.geert+renesas@glider.be>
On Wed, 10 Jun 2026 17:29:20 +0200, Geert Uytterhoeven wrote:
> On Renesas SH-Mobile and R-Mobile SoCs, the ARM PL310 L2 Cache
> Controller is located in a controllable power area.
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---
> This fixes "make dtbs_check":
>
> arch/arm/boot/dts/renesas/r8a7740-armadillo800eva.dtb: cache-controller@f0100000 (arm,pl310-cache): 'power-domains' does not match any of the regexes: '^pinctrl-[0-9]+$'
> from schema $id: http://devicetree.org/schemas/cache/l2c2x0.yaml
> arch/arm/boot/dts/renesas/sh73a0-kzm9g.dtb: cache-controller@f0100000 (arm,pl310-cache): 'power-domains' does not match any of the regexes: '^pinctrl-[0-9]+$'
> from schema $id: http://devicetree.org/schemas/cache/l2c2x0.yaml
> ---
> Documentation/devicetree/bindings/cache/l2c2x0.yaml | 3 +++
> 1 file changed, 3 insertions(+)
>
Applied, thanks!
^ permalink raw reply
* Re: [PATCH v5 1/3] dt-bindings: pwm: Add Raspberry Pi RP1 PWM controller
From: sashiko-bot @ 2026-06-12 14:05 UTC (permalink / raw)
To: Andrea della Porta; +Cc: conor+dt, devicetree, robh
In-Reply-To: <350c2fb454951fd2c9d959f1d94802fea8fa8152.1780670224.git.andrea.porta@suse.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The binding advertises optional DMA support but omits the required `dmas` and `dma-names` properties, causing schema validation to fail for fully-described hardware.
--
commit e8a66b347923785d0769453c48739036bf8237d0
Author: Naushir Patuck <naush@raspberrypi.com>
dt-bindings: pwm: Add Raspberry Pi RP1 PWM controller
This commit adds the devicetree binding documentation for the PWM controller
found in the Raspberry Pi RP1 chipset.
> diff --git a/Documentation/devicetree/bindings/pwm/raspberrypi,rp1-pwm.yaml b/Documentation/devicetree/bindings/pwm/raspberrypi,rp1-pwm.yaml
> new file mode 100644
> index 0000000000000..6f8461d0454f7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pwm/raspberrypi,rp1-pwm.yaml
[ ... ]
> +description: |
> + The PWM peripheral is a flexible waveform generator with a
> + variety of operational modes. It has the following features:
> + - four independent output channels
> + - 32-bit counter widths
> + - Seven output generation modes
> + - Optional per-channel output inversion
> + - Optional duty-cycle data FIFO with DMA support
> + - Optional sigma-delta noise shaping engine
> + Serves as a fan speed provider to other nodes for a PWM-connected
> + fan using shared registers (syscon).
> +
> +properties:
> + compatible:
> + const: raspberrypi,rp1-pwm
> +
> + reg:
> + maxItems: 1
> +
> + clocks:
> + maxItems: 1
> +
> + "#pwm-cells":
> + const: 3
> +
> +required:
> + - compatible
> + - reg
> + - clocks
> +
> +unevaluatedProperties: false
[Severity: Low]
Since the description advertises optional DMA support, should the properties
block also define dmas and dma-names?
With unevaluatedProperties set to false, any device tree node that tries to
describe the hardware's DMA channels will fail schema validation. Even if the
OS driver does not yet implement DMA support, shouldn't the binding fully
describe the hardware capabilities so fully-described nodes aren't rejected?
--
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1780670224.git.andrea.porta@suse.com?part=1
^ permalink raw reply
* Re: [PATCH V11 3/9] iio: imu: inv_icm42607: Add inv_icm42607 Core Driver
From: Chris Morgan @ 2026-06-12 13:59 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Chris Morgan, linux-iio, andy, nuno.sa, dlechner,
jean-baptiste.maneyrol, linux-rockchip, devicetree, heiko,
conor+dt, krzk+dt, robh, andriy.shevchenko
In-Reply-To: <20260612114230.0fd2f391@jic23-huawei>
On Fri, Jun 12, 2026 at 11:42:30AM +0100, Jonathan Cameron wrote:
> On Thu, 11 Jun 2026 11:31:09 -0500
> Chris Morgan <macromorgan@hotmail.com> wrote:
>
> > On Thu, Jun 11, 2026 at 05:20:22PM +0100, Jonathan Cameron wrote:
> > > On Thu, 11 Jun 2026 09:32:38 -0500
> > > Chris Morgan <macromorgan@hotmail.com> wrote:
> > >
> > > > On Thu, Jun 11, 2026 at 12:09:43PM +0100, Jonathan Cameron wrote:
> > > > > On Wed, 10 Jun 2026 12:54:47 -0500
> > > > > Chris Morgan <macroalpha82@gmail.com> wrote:
> > > > >
> > > > > > From: Chris Morgan <macromorgan@hotmail.com>
> > > > > >
> > > > > > Add the core component of a new inv_icm42607 driver. This includes
> > > > > > a few setup functions and the full register definition in the
> > > > > > header file.
> > > > > >
> > > > > > Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
> > > > > Hi Chris,
> > > > >
> > > > > A couple more minor things from a fresh read.
> > > > >
> > > > > Thanks
> > > > >
> > > > > Jonathan
> > > > >
> > > > > > ---
> > > > > > drivers/iio/imu/inv_icm42607/inv_icm42607.h | 334 ++++++++++++++++++
> > > > > > .../iio/imu/inv_icm42607/inv_icm42607_core.c | 197 +++++++++++
> > > > > > 2 files changed, 531 insertions(+)
> > > > > > create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607.h
> > > > > > create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_core.c
> > > > > >
> > > > > > diff --git a/drivers/iio/imu/inv_icm42607/inv_icm42607.h b/drivers/iio/imu/inv_icm42607/inv_icm42607.h
> > > > > > new file mode 100644
> > > > > > index 000000000000..716fc0f1c3fd
> > > > > > --- /dev/null
> > > > > > +++ b/drivers/iio/imu/inv_icm42607/inv_icm42607.h
> > > > >
> > > > > > diff --git a/drivers/iio/imu/inv_icm42607/inv_icm42607_core.c b/drivers/iio/imu/inv_icm42607/inv_icm42607_core.c
> > > > > > new file mode 100644
> > > > > > index 000000000000..334264120b42
> > > > > > --- /dev/null
> > > > > > +++ b/drivers/iio/imu/inv_icm42607/inv_icm42607_core.c
> > > > >
> > > > > > +
> > > > > > +static int inv_icm42607_setup(struct inv_icm42607_state *st,
> > > > > > + inv_icm42607_bus_setup inv_icm42607_bus_setup)
> > > > > > +{
> > > > > > + const struct device *dev = regmap_get_device(st->map);
> > > > > > + unsigned int val;
> > > > > > + int ret;
> > > > > > +
> > > > > > + ret = regmap_read(st->map, INV_ICM42607_REG_WHOAMI, &val);
> > > > > > + if (ret)
> > > > > > + return ret;
> > > > > > +
> > > > > > + /* Warn, but don't fail. */
> > > > > > + if (val != st->hw->whoami)
> > > > > > + dev_warn(dev, "Unknown whoami %#02x expected %#02x (%s)\n",
> > > > > > + val, st->hw->whoami, st->hw->name);
> > > > > > +
> > > > > > + ret = regmap_write(st->map, INV_ICM42607_REG_SIGNAL_PATH_RESET,
> > > > > > + INV_ICM42607_SIGNAL_PATH_RESET_SOFT_RESET);
> > > > > > + if (ret)
> > > > > > + return ret;
> > > > > > +
> > > > > > + fsleep(INV_ICM42607_RESET_TIME_MS * USEC_PER_MSEC);
> > > > > > +
> > > > > > + /*
> > > > > > + * No polling interval specified in datasheet, so use reset time as
> > > > > > + * polling interval and 10x reset time as timeout period.
> > > > > > + */
> > > > > > + ret = regmap_read_poll_timeout(st->map, INV_ICM42607_REG_INT_STATUS,
> > > > > > + val, val & INV_ICM42607_INT_STATUS_RESET_DONE,
> > > > > > + (INV_ICM42607_RESET_TIME_MS * USEC_PER_MSEC),
> > > > > > + (INV_ICM42607_RESET_TIME_MS * USEC_PER_MSEC * 10));
> > > > > > + if (ret)
> > > > > > + return dev_err_probe(dev, ret,
> > > > > > + "reset error, reset done bit not set\n");
> > > > > > +
> > > > > > + /* Sync the regcache again after a reset. */
> > > > > > + regcache_mark_dirty(st->map);
> > > > > > + ret = regcache_sync(st->map);
> > > > >
> > > > > Sashiko raised the point that you don't have a writeable register list for the regmap
> > > > > and so potentially we at very least write a bunch of stuff that isn't needed.
> > > > > I doubt it's actually a problem or you would have seen it, but nice little optimization
> > > > > to reduce what is written.
> > > >
> > > > I will add such a list, I'd put it in patch 4 unless you think I should
> > > > merge patch 3 and 4 to make the driver compileable at the first commit
> > > > of code (will push the number of lines to the ~850/900 range though).
> > > >
> > > I'm fine with them split but don't mind if Andy prefers them combined.
> > > His comment on adding a COMPILE_TEST option would allow that to be
> > > built, but it is a bit odd to do it just for that purpose.
> > >
> > > Jonathan
> > >
> >
> > I'm going to add the i2c stuff to this series, and then do the SPI
> > on the next patch. That should add only a little bit to this one but
> > still ensure the very first (code) commit has something to compile.
> > I'm going to avoid doing COMPILE_TEST unless collectively you all
> > think I should.
> >
> > I'm still racing to try and get this one done before the merge
> > window opens up, but I'm pretty sure it's already too late at
> > this point. I'll refrain from submitting updates once the window opens
> > though.
> Unfortunately you are correct. IIO in practice closes around 10 days before
> the merge window to give time to both expose new things to testing in linux-next
> and to allow time for Greg KH to merge my pull request into char-misc (which
> is the path IIO takes to upstream)
>
> Sorry about that, and whilst no need to rush as a result, we also don't
> stop merging IIO stuff in the merge window, it just sits in the testing
> branch until I can rebase that on rc1 and then push it out for linux-next
> to pick up.
>
> Thanks,
No worries. I think I'm down to 2 bugs with sashiko that I'll try to
quash, then I can move on to other stuff. Note that when it complains
about the temperature sensor and power management that's a false
positive. I tried to put a note there to give it a hint but it doesn't
seem to want to take it.
If I haven't communicated it previously, thank you again for your help
with this. I thought adding an accelerometer to my handheld would be
easy, but I do appreciate everything you and the other maintainers have
helped me with.
Chris
>
> Jonathan
> >
> > Thank you,
> > Chris
> >
>
^ permalink raw reply
* [PATCH v5 3/3] arm64: dts: broadcom: rpi-5: Add RP1 PWM node
From: Andrea della Porta @ 2026-06-12 14:01 UTC (permalink / raw)
To: Uwe Kleine-König, linux-pwm, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
Broadcom internal kernel review list, Andrea della Porta,
devicetree, linux-rpi-kernel, linux-arm-kernel, linux-kernel,
Naushir Patuck, Stanimir Varbanov, mbrugger
In-Reply-To: <cover.1780670224.git.andrea.porta@suse.com>
From: Stanimir Varbanov <svarbanov@suse.de>
The RP1 chipset used on the Raspberry Pi 5 features an integrated
PWM controller to drive the cooling fan.
Add the corresponding DT node for this PWM controller.
Signed-off-by: Stanimir Varbanov <svarbanov@suse.de>
Co-developed-by: Andrea della Porta <andrea.porta@suse.com>
Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
---
arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts | 12 ++++++++++++
arch/arm64/boot/dts/broadcom/rp1-common.dtsi | 9 +++++++++
2 files changed, 21 insertions(+)
diff --git a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
index 0fc57e72632ed..748be8f1ee9e2 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
+++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
@@ -64,6 +64,12 @@ phy1: ethernet-phy@1 {
};
&rp1_gpio {
+ fan_pwm_default_state: fan-pwm-default-state {
+ function = "pwm1";
+ pins = "gpio45";
+ bias-pull-down;
+ };
+
usb_vbus_default_state: usb-vbus-default-state {
function = "vbus1";
groups = "vbus1";
@@ -94,6 +100,12 @@ &rp1_i2c6 {
pinctrl-names = "default";
};
+&rp1_pwm1 {
+ pinctrl-0 = <&fan_pwm_default_state>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
&rp1_usb0 {
pinctrl-0 = <&usb_vbus_default_state>;
pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/broadcom/rp1-common.dtsi b/arch/arm64/boot/dts/broadcom/rp1-common.dtsi
index 16f5359395835..df4c2d09c8d34 100644
--- a/arch/arm64/boot/dts/broadcom/rp1-common.dtsi
+++ b/arch/arm64/boot/dts/broadcom/rp1-common.dtsi
@@ -99,7 +99,16 @@ rp1_i2c6: i2c@40088000 {
clocks = <&rp1_clocks RP1_CLK_SYS>;
i2c-scl-rising-time-ns = <65>;
i2c-scl-falling-time-ns = <100>;
+ status = "disabled";
+ };
+ rp1_pwm1: pwm@4009c000 {
+ compatible = "raspberrypi,rp1-pwm";
+ reg = <0x00 0x4009c000 0x0 0x100>;
+ clocks = <&rp1_clocks RP1_CLK_PWM1>;
+ assigned-clocks = <&rp1_clocks RP1_CLK_PWM1>;
+ assigned-clock-rates = <50000000>;
+ #pwm-cells = <3>;
status = "disabled";
};
--
2.35.3
^ permalink raw reply related
* [PATCH v5 2/3] pwm: rp1: Add RP1 PWM controller driver
From: Andrea della Porta @ 2026-06-12 14:01 UTC (permalink / raw)
To: Uwe Kleine-König, linux-pwm, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
Broadcom internal kernel review list, Andrea della Porta,
devicetree, linux-rpi-kernel, linux-arm-kernel, linux-kernel,
Naushir Patuck, Stanimir Varbanov, mbrugger
In-Reply-To: <cover.1780670224.git.andrea.porta@suse.com>
From: Naushir Patuck <naush@raspberrypi.com>
The Raspberry Pi RP1 southbridge features an embedded PWM
controller with 4 output channels, alongside an RPM interface
to read the fan speed on the Raspberry Pi 5.
Add the supporting driver.
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Co-developed-by: Stanimir Varbanov <svarbanov@suse.de>
Signed-off-by: Stanimir Varbanov <svarbanov@suse.de>
Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
---
drivers/pwm/Kconfig | 9 +
drivers/pwm/Makefile | 1 +
drivers/pwm/pwm-rp1.c | 424 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 434 insertions(+)
create mode 100644 drivers/pwm/pwm-rp1.c
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 6f3147518376a..c3ddc0eb4774f 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -625,6 +625,15 @@ config PWM_ROCKCHIP
Generic PWM framework driver for the PWM controller found on
Rockchip SoCs.
+config PWM_RASPBERRYPI_RP1
+ tristate "RP1 PWM support"
+ depends on MISC_RP1 || COMPILE_TEST
+ depends on HAS_IOMEM
+ select REGMAP_MMIO
+ select MFD_SYSCON
+ help
+ PWM framework driver for Raspberry Pi RP1 controller.
+
config PWM_SAMSUNG
tristate "Samsung PWM support"
depends on PLAT_SAMSUNG || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 0dc0d2b69025d..59f29f60f9123 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_PWM_RENESAS_RZG2L_GPT) += pwm-rzg2l-gpt.o
obj-$(CONFIG_PWM_RENESAS_RZ_MTU3) += pwm-rz-mtu3.o
obj-$(CONFIG_PWM_RENESAS_TPU) += pwm-renesas-tpu.o
obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o
+obj-$(CONFIG_PWM_RASPBERRYPI_RP1) += pwm-rp1.o
obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o
obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o
obj-$(CONFIG_PWM_SL28CPLD) += pwm-sl28cpld.o
diff --git a/drivers/pwm/pwm-rp1.c b/drivers/pwm/pwm-rp1.c
new file mode 100644
index 0000000000000..6382a81a5ea0f
--- /dev/null
+++ b/drivers/pwm/pwm-rp1.c
@@ -0,0 +1,424 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * pwm-rp1.c
+ *
+ * Raspberry Pi RP1 PWM.
+ *
+ * Copyright © 2026 Raspberry Pi Ltd.
+ *
+ * Author: Naushir Patuck (naush@raspberrypi.com)
+ *
+ * Based on the pwm-bcm2835 driver by:
+ * Bart Tanghe <bart.tanghe@thomasmore.be>
+ *
+ * Datasheet: https://pip-assets.raspberrypi.com/categories/892-raspberry-pi-5/documents/RP-008370-DS-1-rp1-peripherals.pdf?disposition=inline
+ *
+ * Limitations:
+ * - Channels can be enabled/disabled through a global update flag, while the
+ * period and duty per-channel registers are independently updatable, and
+ * they are latched on the end of (specific channel) period strobe.
+ * This means that period and duty changes might result in glitches if the
+ * period/duty is changed exactly during an end of period strobe.
+ * - Since the duty/period registers are freely updatable (do not depend on
+ * the global update flag), setting one of them close to the period end and
+ * the other right afterwards results in a mixed output for that cycle because
+ * the write ops are not atomic.
+ * - The global update flag prevents mis-sampling of multi-bit bus signals in
+ * the PWM clock domain. This ensures that all PWM channel settings update
+ * on the same PWM clock cycle. Channels start in sync only if they share the
+ * same period.
+ * - If both duty and period are set to 0, the output is a constant low signal
+ * if polarity is normal or a constant high signal if polarity is inversed.
+ * - When disabled the output is driven to 0 if polarity is normal, or to 1
+ * if polarity is inversed.
+ * - Disabling the PWM stops the output immediately, without waiting for current
+ * period to complete first.
+ * - Channels are phase-capable, but on RPi5, the firmware can use a channel
+ * phase register to report the RPM of the fan connected to that PWM
+ * channel. As a result, phase control will be ignored for now.
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <linux/units.h>
+
+#define RP1_PWM_GLB_CTRL 0x000
+#define RP1_PWM_GLB_CTRL_CHANNEL_ENABLE(chan) BIT(chan)
+#define RP1_PWM_GLB_CTRL_SET_UPDATE BIT(31)
+
+#define RP1_PWM_CHAN_CTRL(chan) (0x014 + ((chan) * 0x10))
+#define RP1_PWM_CHAN_CTRL_POLARITY BIT(3)
+#define RP1_PWM_CHAN_CTRL_FIFO_POP_MASK BIT(8)
+#define RP1_PWM_CHAN_CTRL_MODE GENMASK(2, 0)
+enum rp1_pwm_ctrl_mode {
+ RP1_PWM_CHAN_CTRL_MODE_ZERO,
+ RP1_PWM_CHAN_CTRL_MODE_TE_MS,
+ RP1_PWM_CHAN_CTRL_MODE_PC_MS,
+ RP1_PWM_CHAN_CTRL_MODE_PD_ENC,
+ RP1_PWM_CHAN_CTRL_MODE_MSB_SER,
+ RP1_PWM_CHAN_CTRL_MODE_PPM,
+ RP1_PWM_CHAN_CTRL_MODE_LE_MS,
+ RP1_PWM_CHAN_CTRL_MODE_LSB_SER,
+};
+
+#define RP1_PWM_CHAN_CTRL_DEFAULT (RP1_PWM_CHAN_CTRL_FIFO_POP_MASK + \
+ FIELD_PREP(RP1_PWM_CHAN_CTRL_MODE, \
+ RP1_PWM_CHAN_CTRL_MODE_TE_MS))
+
+#define RP1_PWM_RANGE(chan) (0x018 + ((chan) * 0x10))
+#define RP1_PWM_PHASE(chan) (0x01C + ((chan) * 0x10))
+#define RP1_PWM_DUTY(chan) (0x020 + ((chan) * 0x10))
+
+#define RP1_PWM_NUM_PWMS 4
+
+struct rp1_pwm {
+ struct regmap *regmap;
+ struct clk *clk;
+ unsigned long clk_rate;
+ bool clk_enabled;
+};
+
+struct rp1_pwm_waveform {
+ u32 period_ticks;
+ u32 duty_ticks;
+ bool enabled;
+ bool inverted_polarity;
+};
+
+static const struct regmap_config rp1_pwm_regmap_config = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+ .max_register = 0x60,
+};
+
+static void rp1_pwm_apply_config(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
+ u32 value;
+
+ /* update the changed registers on the next strobe to avoid glitches */
+ regmap_read(rp1->regmap, RP1_PWM_GLB_CTRL, &value);
+ value |= RP1_PWM_GLB_CTRL_SET_UPDATE;
+ regmap_write(rp1->regmap, RP1_PWM_GLB_CTRL, value);
+}
+
+static int rp1_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
+
+ /* init channel to reset defaults, preserving the polarity bit */
+ regmap_update_bits(rp1->regmap, RP1_PWM_CHAN_CTRL(pwm->hwpwm),
+ ~(u32)RP1_PWM_CHAN_CTRL_POLARITY, RP1_PWM_CHAN_CTRL_DEFAULT);
+ return 0;
+}
+
+static int rp1_pwm_round_waveform_tohw(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ const struct pwm_waveform *wf,
+ void *_wfhw)
+{
+ struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
+ u64 period_ticks, duty_ticks, offset_ticks;
+ struct rp1_pwm_waveform *wfhw = _wfhw;
+ u64 clk_rate = rp1->clk_rate;
+ int ret = 0;
+
+ if (!wf->period_length_ns) {
+ wfhw->enabled = false;
+ return 0;
+ }
+
+ period_ticks = mul_u64_u64_div_u64(wf->period_length_ns, clk_rate, NSEC_PER_SEC);
+
+ /*
+ * The period is limited to U32_MAX, and it will be decremented by one later
+ * to allow 100% duty cycle.
+ */
+ if (period_ticks > U32_MAX) {
+ period_ticks = U32_MAX;
+ } else if (period_ticks < 2) {
+ period_ticks = 2;
+ ret = 1;
+ }
+
+ duty_ticks = mul_u64_u64_div_u64(wf->duty_length_ns, clk_rate, NSEC_PER_SEC);
+ duty_ticks = min(duty_ticks, period_ticks);
+ offset_ticks = mul_u64_u64_div_u64(wf->duty_offset_ns, clk_rate, NSEC_PER_SEC);
+ if (offset_ticks >= period_ticks)
+ offset_ticks %= period_ticks;
+ if (duty_ticks && offset_ticks &&
+ duty_ticks + offset_ticks >= period_ticks) {
+ wfhw->duty_ticks = period_ticks - duty_ticks;
+ wfhw->inverted_polarity = true;
+ } else {
+ wfhw->duty_ticks = duty_ticks;
+ wfhw->inverted_polarity = false;
+ }
+ /* Account for the extra tick at the end of the period */
+ wfhw->period_ticks = period_ticks - 1;
+
+ wfhw->enabled = true;
+
+ return ret;
+}
+
+static int rp1_pwm_round_waveform_fromhw(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ const void *_wfhw,
+ struct pwm_waveform *wf)
+{
+ struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
+ const struct rp1_pwm_waveform *wfhw = _wfhw;
+ u64 clk_rate = rp1->clk_rate;
+ u64 ticks;
+
+ *wf = (struct pwm_waveform){ };
+
+ if (!wfhw->enabled)
+ return 0;
+
+ wf->period_length_ns = DIV_ROUND_UP_ULL(((u64)wfhw->period_ticks + 1) * NSEC_PER_SEC,
+ clk_rate);
+
+ if (!wfhw->inverted_polarity) {
+ wf->duty_length_ns = DIV_ROUND_UP_ULL((u64)wfhw->duty_ticks * NSEC_PER_SEC,
+ clk_rate);
+ } else {
+ ticks = (u64)wfhw->period_ticks + 1 - wfhw->duty_ticks;
+ wf->duty_length_ns = DIV_ROUND_UP_ULL(ticks * NSEC_PER_SEC, clk_rate);
+ wf->duty_offset_ns = wf->period_length_ns - wf->duty_length_ns;
+ }
+
+ return 0;
+}
+
+static int rp1_pwm_write_waveform(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ const void *_wfhw)
+{
+ struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
+ const struct rp1_pwm_waveform *wfhw = _wfhw;
+ u32 value, ctrl;
+
+ /* set polarity */
+ regmap_read(rp1->regmap, RP1_PWM_CHAN_CTRL(pwm->hwpwm), &value);
+ if (!wfhw->inverted_polarity)
+ value &= ~RP1_PWM_CHAN_CTRL_POLARITY;
+ else
+ value |= RP1_PWM_CHAN_CTRL_POLARITY;
+ regmap_write(rp1->regmap, RP1_PWM_CHAN_CTRL(pwm->hwpwm), value);
+
+ /* early exit if disabled */
+ regmap_read(rp1->regmap, RP1_PWM_GLB_CTRL, &ctrl);
+ if (!wfhw->enabled) {
+ ctrl &= ~RP1_PWM_GLB_CTRL_CHANNEL_ENABLE(pwm->hwpwm);
+ goto exit_disable;
+ }
+
+ /* set period and duty cycle */
+ regmap_write(rp1->regmap,
+ RP1_PWM_RANGE(pwm->hwpwm), wfhw->period_ticks);
+ regmap_write(rp1->regmap,
+ RP1_PWM_DUTY(pwm->hwpwm), wfhw->duty_ticks);
+
+ /* enable the channel */
+ ctrl |= RP1_PWM_GLB_CTRL_CHANNEL_ENABLE(pwm->hwpwm);
+exit_disable:
+ regmap_write(rp1->regmap, RP1_PWM_GLB_CTRL, ctrl);
+
+ rp1_pwm_apply_config(chip, pwm);
+
+ return 0;
+}
+
+static int rp1_pwm_read_waveform(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ void *_wfhw)
+{
+ struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
+ struct rp1_pwm_waveform *wfhw = _wfhw;
+ u32 value;
+
+ regmap_read(rp1->regmap, RP1_PWM_GLB_CTRL, &value);
+ wfhw->enabled = !!(value & RP1_PWM_GLB_CTRL_CHANNEL_ENABLE(pwm->hwpwm));
+
+ regmap_read(rp1->regmap, RP1_PWM_CHAN_CTRL(pwm->hwpwm), &value);
+ wfhw->inverted_polarity = !!(value & RP1_PWM_CHAN_CTRL_POLARITY);
+
+ if (wfhw->enabled) {
+ regmap_read(rp1->regmap, RP1_PWM_RANGE(pwm->hwpwm), &wfhw->period_ticks);
+ regmap_read(rp1->regmap, RP1_PWM_DUTY(pwm->hwpwm), &wfhw->duty_ticks);
+ } else {
+ wfhw->period_ticks = 0;
+ wfhw->duty_ticks = 0;
+ }
+
+ return 0;
+}
+
+static const struct pwm_ops rp1_pwm_ops = {
+ .sizeof_wfhw = sizeof(struct rp1_pwm_waveform),
+ .request = rp1_pwm_request,
+ .round_waveform_tohw = rp1_pwm_round_waveform_tohw,
+ .round_waveform_fromhw = rp1_pwm_round_waveform_fromhw,
+ .read_waveform = rp1_pwm_read_waveform,
+ .write_waveform = rp1_pwm_write_waveform,
+};
+
+static int rp1_pwm_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ unsigned long clk_rate;
+ struct pwm_chip *chip;
+ void __iomem *base;
+ struct rp1_pwm *rp1;
+ int ret;
+
+ chip = devm_pwmchip_alloc(dev, RP1_PWM_NUM_PWMS, sizeof(*rp1));
+ if (IS_ERR(chip))
+ return PTR_ERR(chip);
+
+ rp1 = pwmchip_get_drvdata(chip);
+
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ rp1->regmap = devm_regmap_init_mmio(dev, base, &rp1_pwm_regmap_config);
+ if (IS_ERR(rp1->regmap))
+ return dev_err_probe(dev, PTR_ERR(rp1->regmap), "Cannot initialize regmap\n");
+
+ rp1->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(rp1->clk))
+ return dev_err_probe(dev, PTR_ERR(rp1->clk), "Clock not found\n");
+
+ ret = clk_prepare_enable(rp1->clk);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to enable clock\n");
+ rp1->clk_enabled = true;
+
+ ret = devm_clk_rate_exclusive_get(dev, rp1->clk);
+ if (ret) {
+ dev_err_probe(dev, ret, "Failed to get exclusive rate\n");
+ goto err_disable_clk;
+ }
+
+ clk_rate = clk_get_rate(rp1->clk);
+ if (!clk_rate) {
+ ret = dev_err_probe(dev, -EINVAL, "Failed to get clock rate\n");
+ goto err_disable_clk;
+ }
+ /*
+ * To prevent u64 overflow in period calculations:
+ * mul_u64_u64_div_u64(period_ns, clk_rate, NSEC_PER_SEC)
+ * If clk_rate > 1 GHz, the result can overflow.
+ */
+ if (clk_rate > HZ_PER_GHZ) {
+ ret = dev_err_probe(dev, -EINVAL, "Clock rate > 1 GHz is not supported\n");
+ goto err_disable_clk;
+ }
+ rp1->clk_rate = clk_rate;
+
+ chip->ops = &rp1_pwm_ops;
+
+ platform_set_drvdata(pdev, chip);
+
+ ret = pwmchip_add(chip);
+ if (ret) {
+ dev_err_probe(dev, ret, "Failed to register PWM chip\n");
+ goto err_disable_clk;
+ }
+
+ ret = of_syscon_register_regmap(np, rp1->regmap);
+ if (ret) {
+ dev_err_probe(dev, ret, "Failed to register syscon\n");
+ goto err_remove_chip;
+ }
+
+ return 0;
+
+err_remove_chip:
+ pwmchip_remove(chip);
+err_disable_clk:
+ clk_disable_unprepare(rp1->clk);
+
+ return ret;
+}
+
+static void rp1_pwm_remove(struct platform_device *pdev)
+{
+ struct pwm_chip *chip = platform_get_drvdata(pdev);
+ struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
+
+ pwmchip_remove(chip);
+
+ if (rp1->clk_enabled) {
+ clk_disable_unprepare(rp1->clk);
+ rp1->clk_enabled = false;
+ }
+}
+
+static int rp1_pwm_suspend(struct device *dev)
+{
+ struct pwm_chip *chip = dev_get_drvdata(dev);
+ struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
+
+ if (rp1->clk_enabled) {
+ clk_disable_unprepare(rp1->clk);
+ rp1->clk_enabled = false;
+ }
+
+ return 0;
+}
+
+static int rp1_pwm_resume(struct device *dev)
+{
+ struct pwm_chip *chip = dev_get_drvdata(dev);
+ struct rp1_pwm *rp1 = pwmchip_get_drvdata(chip);
+ int ret;
+
+ ret = clk_prepare_enable(rp1->clk);
+ if (ret) {
+ dev_err(dev, "Failed to enable clock on resume: %pe\n", ERR_PTR(ret));
+ return ret;
+ }
+
+ rp1->clk_enabled = true;
+
+ return 0;
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(rp1_pwm_pm_ops, rp1_pwm_suspend, rp1_pwm_resume);
+
+static const struct of_device_id rp1_pwm_of_match[] = {
+ { .compatible = "raspberrypi,rp1-pwm" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, rp1_pwm_of_match);
+
+static struct platform_driver rp1_pwm_driver = {
+ .probe = rp1_pwm_probe,
+ .remove = rp1_pwm_remove,
+ .driver = {
+ .name = "rp1-pwm",
+ .of_match_table = rp1_pwm_of_match,
+ .pm = pm_ptr(&rp1_pwm_pm_ops),
+ .suppress_bind_attrs = true,
+ },
+};
+builtin_platform_driver(rp1_pwm_driver);
+
+MODULE_DESCRIPTION("RP1 PWM driver");
+MODULE_AUTHOR("Naushir Patuck <naush@raspberrypi.com>");
+MODULE_AUTHOR("Andrea della Porta <andrea.porta@suse.com>");
+MODULE_LICENSE("GPL");
--
2.35.3
^ permalink raw reply related
* [PATCH v5 1/3] dt-bindings: pwm: Add Raspberry Pi RP1 PWM controller
From: Andrea della Porta @ 2026-06-12 14:01 UTC (permalink / raw)
To: Uwe Kleine-König, linux-pwm, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
Broadcom internal kernel review list, Andrea della Porta,
devicetree, linux-rpi-kernel, linux-arm-kernel, linux-kernel,
Naushir Patuck, Stanimir Varbanov, mbrugger
Cc: Krzysztof Kozlowski
In-Reply-To: <cover.1780670224.git.andrea.porta@suse.com>
From: Naushir Patuck <naush@raspberrypi.com>
Add the devicetree binding documentation for the PWM
controller found in the Raspberry Pi RP1 chipset.
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Co-developed-by: Stanimir Varbanov <svarbanov@suse.de>
Signed-off-by: Stanimir Varbanov <svarbanov@suse.de>
Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
---
.../bindings/pwm/raspberrypi,rp1-pwm.yaml | 54 +++++++++++++++++++
1 file changed, 54 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pwm/raspberrypi,rp1-pwm.yaml
diff --git a/Documentation/devicetree/bindings/pwm/raspberrypi,rp1-pwm.yaml b/Documentation/devicetree/bindings/pwm/raspberrypi,rp1-pwm.yaml
new file mode 100644
index 0000000000000..6f8461d0454f7
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/raspberrypi,rp1-pwm.yaml
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/raspberrypi,rp1-pwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Raspberry Pi RP1 PWM controller
+
+maintainers:
+ - Naushir Patuck <naush@raspberrypi.com>
+
+allOf:
+ - $ref: pwm.yaml#
+
+description: |
+ The PWM peripheral is a flexible waveform generator with a
+ variety of operational modes. It has the following features:
+ - four independent output channels
+ - 32-bit counter widths
+ - Seven output generation modes
+ - Optional per-channel output inversion
+ - Optional duty-cycle data FIFO with DMA support
+ - Optional sigma-delta noise shaping engine
+ Serves as a fan speed provider to other nodes for a PWM-connected
+ fan using shared registers (syscon).
+
+properties:
+ compatible:
+ const: raspberrypi,rp1-pwm
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ "#pwm-cells":
+ const: 3
+
+required:
+ - compatible
+ - reg
+ - clocks
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ pwm@98000 {
+ compatible = "raspberrypi,rp1-pwm";
+ reg = <0x98000 0x100>;
+ clocks = <&rp1_clocks 17>;
+ #pwm-cells = <3>;
+ };
--
2.35.3
^ permalink raw reply related
* [PATCH v5 0/3] Add RP1 PWM controller support
From: Andrea della Porta @ 2026-06-12 14:01 UTC (permalink / raw)
To: Uwe Kleine-König, linux-pwm, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
Broadcom internal kernel review list, Andrea della Porta,
devicetree, linux-rpi-kernel, linux-arm-kernel, linux-kernel,
Naushir Patuck, Stanimir Varbanov, mbrugger
This patchset adds support for the PWM controller found on the
Raspberry Pi RP1 southbridge. This is necessary to operate the
cooling fan connected to one of the PWM channels.
The tachometer pin for the fan speed is managed by the firmware
running on the RP1's M-core. It uses the PHASE2 register
to report the RPM, which is then exported by this driver via
syscon registers. A subsequent patch will add a new device
and driver to read the RPM and export this value via hwmon.
Subsequent patches will also add the CPU thermal zone, which
acts as a consumer of the PWM device.
Best regards,
Andrea
CHANGES in V5:
- period_tick is now capped to U32_MAX to avoid breaking
monotonicity
- period_ticks less than 2 are set to 2
- fixed two casts in fromhw() that could led to an incorrect
truncation/underflow
- when disabling a pwm channel, first set the polarity to
avoid unintended quiescent level
- in probe function, fixed and error path that could leak
an invalid pwm_chip struct
Naushir Patuck (2):
dt-bindings: pwm: Add Raspberry Pi RP1 PWM controller
pwm: rp1: Add RP1 PWM controller driver
Stanimir Varbanov (1):
arm64: dts: broadcom: rpi-5: Add RP1 PWM node
.../bindings/pwm/raspberrypi,rp1-pwm.yaml | 54 +++
.../boot/dts/broadcom/bcm2712-rpi-5-b.dts | 12 +
arch/arm64/boot/dts/broadcom/rp1-common.dtsi | 9 +
drivers/pwm/Kconfig | 9 +
drivers/pwm/Makefile | 1 +
drivers/pwm/pwm-rp1.c | 424 ++++++++++++++++++
6 files changed, 509 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pwm/raspberrypi,rp1-pwm.yaml
create mode 100644 drivers/pwm/pwm-rp1.c
--
2.35.3
^ permalink raw reply
* Re: [PATCH 2/2] dt-bindings: iio: dac: adi,ad5337: add dt-bindings
From: Joshua Crofts @ 2026-06-12 13:58 UTC (permalink / raw)
To: Marcin Bis; +Cc: linux-iio, devicetree
In-Reply-To: <20260612133125.196208-2-marcin@bis-linux.com>
On Fri, 12 Jun 2026 15:31:22 +0200
Marcin Bis <marcin@bis-linux.com> wrote:
> Add dt-bindings for the AD5337 dual 8-bit I2C voltage-output DAC driver.
>
> Signed-off-by: Marcin Bis <marcin@bis-linux.com>
> ---
If you're adding new device support, any dt-binding patches
should go first in the series.
Another big problem is that you haven't cc'd any devicetree
maintainers/reviewers, nor the devicetree mailing list, therefore
they probably won't see this patch and their automated tooling
definitely won't check this. If you're unsure where to send this
patch to, use the get_maintainer.pl script.
Also, it seems that you've replied with this patch to the
first patch in the series, making it appear strangely in my
(and probably other people's) email clients. Use a cover
letter when sending patch series, it prevents things like
this from happening.
+cc'd devicetree@vger.kernel.org
--
Kind regards
CJD
^ permalink raw reply
* Re: [PATCH v3 1/8] dt-bindings: remoteproc: qcom,pas: add thermal mitigation properties
From: Gaurav Kohli @ 2026-06-12 13:52 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Manivannan Sadhasivam, Konrad Dybcio, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers, linux-arm-msm,
linux-remoteproc, devicetree, linux-kernel, linux-pm,
linux-hardening, Manaf Meethalavalappu Pallikunhi
In-Reply-To: <d81bc78e-2c1d-45fd-90c9-f7ec462183a0@kernel.org>
On 6/11/2026 5:53 PM, Krzysztof Kozlowski wrote:
> On 11/06/2026 13:12, Gaurav Kohli wrote:
>>> Why? And where is this generic property defined? You cannot just
>>> sprinkle generic properties in random bindings.
>>>
>>
>> Ack, will add why part.
>> These names are matched with the thermal mitigation device identifiers
>> populated by remote firmware over QMI and define mitigation devices are
>> exposed as cooling devices.
>
> No, -names correspond to values passed via DT, not some remote firmware.
> The remote firmware should give you interface which is explicit and does
> not need such properties.
thanks Krzysztof for review, We need tmd-names because of following reasons:
Following Daniel's series [1], the thermal framework supports
mapping multiple cooling devices per remoteproc/device via indexed
cooling-cells.
1) The thermal framework's cooling-maps reference
cooling devices by index (for #cooling-cells = <3>). Without tmd-names,
there's no way to know which index corresponds to which TMD, as firmware
may return tmd-names in any order.
below are the changes post new thermal mapping changes:
DT: tmd-names = "cdsp_sw", "xyz";
Firmware: ["cdsp_sw", "xyz1", "xyz2",]
Driver registers: Only "cdsp_sw" (index 0) and "xyz" (index 1)
This allows cooling-maps like below:
cooling-device = <&remoteproc 0 ...> // "cdsp_sw"
cooling-device = <&remoteproc 1 ...> // "xyz"
2) Not all firmware-provided TMDs should be
exposed as cooling devices. The tmd-names property acts as a filter,
allowing board-specific DT to select only the relevant TMDs for that
platform.
[1]
https://lore.kernel.org/all/20260526140802.1059293-12-daniel.lezcano@oss.qualcomm.com/
>
>>
>> Without tmd-names in DT, it is unclear which index corresponds to which
>> binding. With #cooling-cells, tmd-names in DT provides an explicit
>> name-to-index mapping. Please suggest.
>
> I don't get what is the index here. Index of what?
>
>
> Best regards,
> Krzysztof
^ permalink raw reply
* RE: [PATCH v17 00/17] Add Renesas RZ/G3L SD/eMMC support
From: Biju Das @ 2026-06-12 13:51 UTC (permalink / raw)
To: Biju Das, wsa+renesas
Cc: biju.das.au, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Geert Uytterhoeven, Philipp Zabel, magnus.damm,
linux-mmc@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org,
Prabhakar Mahadev Lad
In-Reply-To: <TY3PR01MB1134651DFD308D3DD8AB20FE386132@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Hi Wolfram,
I found some bugs in RZ/G3L in between
1) SH_MOBILE_SDHI_SCC_TMPPORT2_HS400OSEL bit is not available in RZ/G3L, but instead used
as timing value 16 instead of 1.
2) RZ/G3L needs to set HWADJ2 delays for 3.3V and 1.8V operation
3) When I added HS400 mode support, forgot to retain HS400 bits (HS400EN and HS400ENHSTRB) in
renesas_sdhi_execute_tuning()
I will send v3 with these changes, if it is ok for you.
Cheers,
Biju
> -----Original Message-----
> From: Biju Das <biju.das.jz@bp.renesas.com>
> Sent: 03 June 2026 08:27
> Subject: RE: [PATCH v17 00/17] Add Renesas RZ/G3L SD/eMMC support
>
> Hi Wolfram,
>
> Thanks for the feedback.
>
> > -----Original Message-----
> > From: wsa+renesas <wsa+renesas@sang-engineering.com>
> > Sent: 03 June 2026 08:19
> > Subject: Re: [PATCH v17 00/17] Add Renesas RZ/G3L SD/eMMC support
> >
> >
> > > I will fix the issue soon.
> >
> > No need to resend from my POV.
>
> I will wait for review comments then.
>
> Cheers,
> Biju
^ permalink raw reply
* Re: [PATCH v4 05/16] riscv: Add Zicclsm to cpufeature and hwprobe
From: Jesse Taube @ 2026-06-12 13:51 UTC (permalink / raw)
To: Guodong Xu
Cc: Jonathan Corbet, Shuah Khan, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Alexandre Ghiti, Zong Li, Deepak Gupta, Anup Patel,
Atish Patra, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Yixun Lan, Chen Wang, Inochi Amaoto, linux-doc, linux-riscv,
linux-kernel, kvm, kvm-riscv, Paul Walmsley, Conor Dooley,
devicetree, spacemit, sophgo, linux-kselftest, Palmer Dabbelt,
Jesse Taube, Conor Dooley, Charlie Jenkins, Andrew Jones,
Andy Chiu
In-Reply-To: <20260611-rva23u64-hwprobe-v2-v4-5-3f01a2449488@gmail.com>
On Thu, Jun 11, 2026 at 4:14 PM Guodong Xu <docular.xu@gmail.com> wrote:
>
> From: Jesse Taube <jesse@rivosinc.com>
>
> Zicclsm requires misaligned support for all regular load and store
> instructions, both scalar and vector, but not AMOs or other
> specialized forms of memory access, to main memory regions with both
> the cacheability and coherence PMAs, as defined in the profiles spec.
> Even though mandated, misaligned loads and stores might execute
> extremely slowly. Standard software distributions should assume their
> existence only for correctness, not for performance.
>
> Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
> Reviewed-by: Andy Chiu <andy.chiu@sifive.com>
> Reviewed-by: Charlie Jenkins <charlie@rivosinc.com>
> Tested-by: Charlie Jenkins <charlie@rivosinc.com>
> Signed-off-by: Jesse Taube <jesse@rivosinc.com>
Thanks for the update! Just an fyi email has changed to
jtaubepe@redhat.com though.
No need to change the signoff though.
Thanks,
Jesse Taube
> [Rebased, rewrote doc text, minor commit message revisions]
> Signed-off-by: Andrew Jones <andrew.jones@oss.qualcomm.com>
> Signed-off-by: Guodong Xu <docular.xu@gmail.com>
>
> ---
> v4: No change.
> v3:
> - Move the hwprobe.rst entry to the IMA_EXT_1 section so its
> documentation matches the IMA_EXT_1 bit it was allocated in v2
> (Sashiko, agreed by Andrew).
> v2:
> - Rebased onto v7.1-rc2; moved ZICCLSM to IMA_EXT_1 and
> allocated a new bit for it
> ---
> Documentation/arch/riscv/hwprobe.rst | 4 ++++
> arch/riscv/include/asm/hwcap.h | 1 +
> arch/riscv/include/uapi/asm/hwprobe.h | 1 +
> arch/riscv/kernel/cpufeature.c | 1 +
> arch/riscv/kernel/sys_hwprobe.c | 1 +
> 5 files changed, 8 insertions(+)
>
> diff --git a/Documentation/arch/riscv/hwprobe.rst b/Documentation/arch/riscv/hwprobe.rst
> index d9928641deb99..49d9fb68632d0 100644
> --- a/Documentation/arch/riscv/hwprobe.rst
> +++ b/Documentation/arch/riscv/hwprobe.rst
> @@ -401,3 +401,7 @@ The following keys are defined:
> as defined in version 1.0 of the RISC-V Control-flow Integrity (CFI)
> extensions specification, ratified in commit 302a2d45c243
> ("Update build-pdf.yml") of riscv-cfi.
> +
> + * :c:macro:`RISCV_HWPROBE_EXT_ZICCLSM`: The Zicclsm extension is supported,
> + as defined in the RISC-V Profiles specification starting from commit
> + b1d80660 ("Updated to ratified state.")
> diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
> index 44bf8c7d8acc5..e8f4a7dd96a93 100644
> --- a/arch/riscv/include/asm/hwcap.h
> +++ b/arch/riscv/include/asm/hwcap.h
> @@ -112,6 +112,7 @@
> #define RISCV_ISA_EXT_ZCLSD 103
> #define RISCV_ISA_EXT_ZICFILP 104
> #define RISCV_ISA_EXT_ZICFISS 105
> +#define RISCV_ISA_EXT_ZICCLSM 106
>
> #define RISCV_ISA_EXT_XLINUXENVCFG 127
>
> diff --git a/arch/riscv/include/uapi/asm/hwprobe.h b/arch/riscv/include/uapi/asm/hwprobe.h
> index 9139edba0aecb..6819df159c51e 100644
> --- a/arch/riscv/include/uapi/asm/hwprobe.h
> +++ b/arch/riscv/include/uapi/asm/hwprobe.h
> @@ -116,6 +116,7 @@ struct riscv_hwprobe {
> #define RISCV_HWPROBE_KEY_ZICBOP_BLOCK_SIZE 15
> #define RISCV_HWPROBE_KEY_IMA_EXT_1 16
> #define RISCV_HWPROBE_EXT_ZICFISS (1ULL << 0)
> +#define RISCV_HWPROBE_EXT_ZICCLSM (1ULL << 1)
>
> /* Increase RISCV_HWPROBE_MAX_KEY when adding items. */
>
> diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
> index 686dde3ce3b98..1fb595581adcf 100644
> --- a/arch/riscv/kernel/cpufeature.c
> +++ b/arch/riscv/kernel/cpufeature.c
> @@ -502,6 +502,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
> __RISCV_ISA_EXT_SUPERSET_VALIDATE(zicbom, RISCV_ISA_EXT_ZICBOM, riscv_xlinuxenvcfg_exts, riscv_ext_zicbom_validate),
> __RISCV_ISA_EXT_DATA_VALIDATE(zicbop, RISCV_ISA_EXT_ZICBOP, riscv_ext_zicbop_validate),
> __RISCV_ISA_EXT_SUPERSET_VALIDATE(zicboz, RISCV_ISA_EXT_ZICBOZ, riscv_xlinuxenvcfg_exts, riscv_ext_zicboz_validate),
> + __RISCV_ISA_EXT_DATA(zicclsm, RISCV_ISA_EXT_ZICCLSM),
> __RISCV_ISA_EXT_DATA(ziccrse, RISCV_ISA_EXT_ZICCRSE),
> __RISCV_ISA_EXT_SUPERSET_VALIDATE(zicfilp, RISCV_ISA_EXT_ZICFILP, riscv_xlinuxenvcfg_exts,
> riscv_cfilp_validate),
> diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c
> index f8f68ba781b45..9cf62266f1890 100644
> --- a/arch/riscv/kernel/sys_hwprobe.c
> +++ b/arch/riscv/kernel/sys_hwprobe.c
> @@ -205,6 +205,7 @@ static void hwprobe_isa_ext1(struct riscv_hwprobe *pair,
> * in the hart_isa bitmap, are made.
> */
> EXT_KEY(isainfo->isa, ZICFISS, pair->value, missing);
> + EXT_KEY(isainfo->isa, ZICCLSM, pair->value, missing);
> }
>
> /* Now turn off reporting features if any CPU is missing it. */
>
> --
> 2.43.0
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox