Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net v3 1/3] net/sched: cls_fw: fix NULL pointer dereference on shared blocks
From: patchwork-bot+netdevbpf @ 2026-04-02 13:20 UTC (permalink / raw)
  To: Xiang Mei
  Cc: netdev, jhs, jiri, davem, edumazet, kuba, horms, shuah, bestswngs
In-Reply-To: <20260331050217.504278-1-xmei5@asu.edu>

Hello:

This series was applied to netdev/net.git (main)
by Paolo Abeni <pabeni@redhat.com>:

On Mon, 30 Mar 2026 22:02:15 -0700 you wrote:
> The old-method path in fw_classify() calls tcf_block_q() and
> dereferences q->handle.  Shared blocks leave block->q NULL, causing a
> NULL deref when an empty cls_fw filter is attached to a shared block
> and a packet with a nonzero major skb mark is classified.
> 
> Reject the configuration in fw_change() when the old method (no
> TCA_OPTIONS) is used on a shared block, since fw_classify()'s
> old-method path needs block->q which is NULL for shared blocks.
> 
> [...]

Here is the summary with links:
  - [net,v3,1/3] net/sched: cls_fw: fix NULL pointer dereference on shared blocks
    https://git.kernel.org/netdev/net/c/faeea8bbf6e9
  - [net,v3,2/3] net/sched: cls_flow: fix NULL pointer dereference on shared blocks
    https://git.kernel.org/netdev/net/c/1a280dd4bd1d
  - [net,v3,3/3] selftests/tc-testing: add tests for cls_fw and cls_flow on shared blocks
    https://git.kernel.org/netdev/net/c/70f73562d278

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply

* [PATCH net-next v4 3/3] net: phy: add a PHY write barrier when disabling interrupts
From: Charles Perry @ 2026-04-02 13:12 UTC (permalink / raw)
  To: netdev
  Cc: Charles Perry, Andrew Lunn, Heiner Kallweit, Russell King,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	linux-kernel
In-Reply-To: <20260402131229.319599-1-charles.perry@microchip.com>

MDIO bus controllers are not required to wait for write transactions to
complete before returning as synchronization is often achieved by polling
status bits.

This can cause issues when disabling interrupts since an interrupt could
fire before the interrupt handler is unregistered and there's no status
bit to poll.

Add a phy_write_barrier() function and use it in phy_disable_interrupts()
to fix this issue. The write barrier just reads an MII register and
discards the value, which is enough to guarantee that previous writes have
completed.

Signed-off-by: Charles Perry <charles.perry@microchip.com>
---

Notes:
    Changes in v4:
      - Add this patch (Russell, Andrew)

 drivers/net/phy/phy.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 13dd1691886d..2be0b90e9947 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -1368,14 +1368,39 @@ void phy_error(struct phy_device *phydev)
 }
 EXPORT_SYMBOL(phy_error);
 
+/**
+ * phy_write_barrier - ensure the last write completed for this PHY device
+ * @phydev: target phy_device struct
+ *
+ * MDIO bus controllers are not required to wait for write transactions to
+ * complete before returning. Calling this function ensures that the previous
+ * write has completed.
+ */
+static int phy_write_barrier(struct phy_device *phydev)
+{
+	int err;
+
+	err = phy_read(phydev, MII_PHYSID1);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
 /**
  * phy_disable_interrupts - Disable the PHY interrupts from the PHY side
  * @phydev: target phy_device struct
  */
 int phy_disable_interrupts(struct phy_device *phydev)
 {
+	int err;
+
 	/* Disable PHY interrupts */
-	return phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED);
+	err = phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED);
+	if (err)
+		return err;
+
+	return phy_write_barrier(phydev);
 }
 
 /**
-- 
2.47.3


^ permalink raw reply related

* [PATCH net-next v4 1/3] dt-bindings: net: document Microchip PIC64-HPSC/HX MDIO controller
From: Charles Perry @ 2026-04-02 13:12 UTC (permalink / raw)
  To: netdev
  Cc: Charles Perry, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, devicetree, linux-kernel
In-Reply-To: <20260402131229.319599-1-charles.perry@microchip.com>

This MDIO hardware is based on a Microsemi design supported in Linux by
mdio-mscc-miim.c. However, The register interface is completely different
with pic64hpsc, hence the need for separate documentation.

The hardware supports C22 and C45.

The documentation recommends an input clock of 156.25MHz and a prescaler
of 39, which yields an MDIO clock of 1.95MHz.

The hardware supports an interrupt pin to signal transaction completion
which is not strictly needed as the software can also poll a "TRIGGER"
bit for this.

Signed-off-by: Charles Perry <charles.perry@microchip.com>
---

Notes:
    Changes in v4: none
    Changes in v3: none
    
    Changes in v2:
      - Make "clocks" and "interrupts" required (Andrew)
      - Add a default value to "clock-frequency" (Andrew)

 .../net/microchip,pic64hpsc-mdio.yaml         | 68 +++++++++++++++++++
 1 file changed, 68 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/microchip,pic64hpsc-mdio.yaml

diff --git a/Documentation/devicetree/bindings/net/microchip,pic64hpsc-mdio.yaml b/Documentation/devicetree/bindings/net/microchip,pic64hpsc-mdio.yaml
new file mode 100644
index 000000000000..d690afe3d3cf
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/microchip,pic64hpsc-mdio.yaml
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/microchip,pic64hpsc-mdio.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip PIC64-HPSC/HX MDIO controller
+
+maintainers:
+  - Charles Perry <charles.perry@microchip.com>
+
+description: |
+  Microchip PIC64-HPSC/HX SoCs have two MDIO bus controller. This MDIO bus
+  controller supports C22 and C45 register access. It is named "MDIO Initiator"
+  in the documentation.
+
+allOf:
+  - $ref: mdio.yaml#
+
+properties:
+  compatible:
+    oneOf:
+      - const: microchip,pic64hpsc-mdio
+      - items:
+          - const: microchip,pic64hx-mdio
+          - const: microchip,pic64hpsc-mdio
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-frequency:
+    default: 2500000
+
+  interrupts:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - interrupts
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    bus {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        mdio@4000C21E000 {
+            compatible = "microchip,pic64hpsc-mdio";
+            reg = <0x400 0x0C21E000 0x0 0x1000>;
+            #address-cells = <1>;
+            #size-cells = <0>;
+            clocks = <&svc_clk>;
+            interrupt-parent = <&saplic0>;
+            interrupts = <168 IRQ_TYPE_LEVEL_HIGH>;
+
+            phy0: ethernet-phy@0 {
+                reg = <0>;
+            };
+        };
+    };
-- 
2.47.3


^ permalink raw reply related

* [PATCH net-next v4 2/3] net: mdio: add a driver for PIC64-HPSC/HX MDIO controller
From: Charles Perry @ 2026-04-02 13:12 UTC (permalink / raw)
  To: netdev
  Cc: Charles Perry, Maxime Chevallier, Andrew Lunn, Heiner Kallweit,
	Russell King, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, linux-kernel
In-Reply-To: <20260402131229.319599-1-charles.perry@microchip.com>

This adds an MDIO driver for PIC64-HPSC/HX. The hardware supports C22
and C45 but only C22 is implemented in this commit.

This MDIO hardware is based on a Microsemi design supported in Linux by
mdio-mscc-miim.c. However, The register interface is completely
different with pic64hpsc, hence the need for a separate driver.

The documentation recommends an input clock of 156.25MHz and a prescaler
of 39, which yields an MDIO clock of 1.95MHz.

The hardware supports an interrupt pin or a "TRIGGER" bit that can be
polled to signal transaction completion. This commit uses polling.

This was tested on Microchip HB1301 evalkit with a VSC8574 and a
VSC8541.

Signed-off-by: Charles Perry <charles.perry@microchip.com>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---

Notes:
    Changes in v4:
      - read: return FIELD_GET() directly instead of using "ret" (Russell)
    
    Changes in v3:
      - Add a MAINTAINERS entry (Jakub)
    
    Changes in v2:
      - Remove #define for unused registers (Maxime)
      - Add "c22" to clause 22 read/write ops (Maxime)
      - Remove the call to platform_set_drvdata() (Andrew)
      - Make the clock mandatory (Andrew)
      - Use 2.5MHz if no clock-frequency was specified (Andrew)
      - Change the error message for bad clock-frequency (Andrew)
      - Fix a use without initialization on bus_freq (Andrew)

 MAINTAINERS                       |   6 +
 drivers/net/mdio/Kconfig          |   7 ++
 drivers/net/mdio/Makefile         |   1 +
 drivers/net/mdio/mdio-pic64hpsc.c | 190 ++++++++++++++++++++++++++++++
 4 files changed, 204 insertions(+)
 create mode 100644 drivers/net/mdio/mdio-pic64hpsc.c

diff --git a/MAINTAINERS b/MAINTAINERS
index e08767323763..9297c46dba91 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17216,6 +17216,12 @@ L:	linux-serial@vger.kernel.org
 S:	Maintained
 F:	drivers/tty/serial/8250/8250_pci1xxxx.c
 
+MICROCHIP PIC64-HPSC/HX DRIVERS
+M:	Charles Perry <charles.perry@microchip.com>
+S:	Supported
+F:	Documentation/devicetree/bindings/net/microchip,pic64hpsc-mdio.yaml
+F:	drivers/net/mdio/mdio-pic64hpsc.c
+
 MICROCHIP POLARFIRE FPGA DRIVERS
 M:	Conor Dooley <conor.dooley@microchip.com>
 L:	linux-fpga@vger.kernel.org
diff --git a/drivers/net/mdio/Kconfig b/drivers/net/mdio/Kconfig
index 44380378911b..7bdba8c3ddef 100644
--- a/drivers/net/mdio/Kconfig
+++ b/drivers/net/mdio/Kconfig
@@ -146,6 +146,13 @@ config MDIO_OCTEON
 	  buses. It is required by the Octeon and ThunderX ethernet device
 	  drivers on some systems.
 
+config MDIO_PIC64HPSC
+	tristate "PIC64-HPSC/HX MDIO interface support"
+	depends on HAS_IOMEM && OF_MDIO
+	help
+	  This driver supports the MDIO interface found on the PIC64-HPSC/HX
+	  SoCs.
+
 config MDIO_IPQ4019
 	tristate "Qualcomm IPQ4019 MDIO interface support"
 	depends on HAS_IOMEM && OF_MDIO
diff --git a/drivers/net/mdio/Makefile b/drivers/net/mdio/Makefile
index fbec636700e7..048586746026 100644
--- a/drivers/net/mdio/Makefile
+++ b/drivers/net/mdio/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_MDIO_MOXART)		+= mdio-moxart.o
 obj-$(CONFIG_MDIO_MSCC_MIIM)		+= mdio-mscc-miim.o
 obj-$(CONFIG_MDIO_MVUSB)		+= mdio-mvusb.o
 obj-$(CONFIG_MDIO_OCTEON)		+= mdio-octeon.o
+obj-$(CONFIG_MDIO_PIC64HPSC)		+= mdio-pic64hpsc.o
 obj-$(CONFIG_MDIO_REALTEK_RTL9300)	+= mdio-realtek-rtl9300.o
 obj-$(CONFIG_MDIO_REGMAP)		+= mdio-regmap.o
 obj-$(CONFIG_MDIO_SUN4I)		+= mdio-sun4i.o
diff --git a/drivers/net/mdio/mdio-pic64hpsc.c b/drivers/net/mdio/mdio-pic64hpsc.c
new file mode 100644
index 000000000000..28be77ad6cf7
--- /dev/null
+++ b/drivers/net/mdio/mdio-pic64hpsc.c
@@ -0,0 +1,190 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Microchip PIC64-HPSC/HX MDIO controller driver
+ *
+ * Copyright (c) 2026 Microchip Technology Inc. and its subsidiaries.
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_mdio.h>
+#include <linux/platform_device.h>
+
+#define MDIO_REG_PRESCALER     0x20
+#define MDIO_CFG_PRESCALE_MASK GENMASK(7, 0)
+
+#define MDIO_REG_FRAME_CFG_1 0x24
+#define MDIO_WDATA_MASK	     GENMASK(15, 0)
+
+#define MDIO_REG_FRAME_CFG_2	 0x28
+#define MDIO_TRIGGER_BIT	 BIT(31)
+#define MDIO_REG_DEV_ADDR_MASK	 GENMASK(20, 16)
+#define MDIO_PHY_PRT_ADDR_MASK	 GENMASK(8, 4)
+#define MDIO_OPERATION_MASK	 GENMASK(3, 2)
+#define MDIO_START_OF_FRAME_MASK GENMASK(1, 0)
+
+/* Possible value of MDIO_OPERATION_MASK */
+#define MDIO_OPERATION_WRITE BIT(0)
+#define MDIO_OPERATION_READ  BIT(1)
+
+#define MDIO_REG_FRAME_STATUS 0x2C
+#define MDIO_READOK_BIT	      BIT(24)
+#define MDIO_RDATA_MASK	      GENMASK(15, 0)
+
+struct pic64hpsc_mdio_dev {
+	void __iomem *regs;
+};
+
+static int pic64hpsc_mdio_wait_trigger(struct mii_bus *bus)
+{
+	struct pic64hpsc_mdio_dev *priv = bus->priv;
+	u32 val;
+	int ret;
+
+	/* The MDIO_TRIGGER bit returns 0 when a transaction has completed. */
+	ret = readl_poll_timeout(priv->regs + MDIO_REG_FRAME_CFG_2, val,
+				 !(val & MDIO_TRIGGER_BIT), 50, 10000);
+
+	if (ret < 0)
+		dev_dbg(&bus->dev, "TRIGGER bit timeout: %x\n", val);
+
+	return ret;
+}
+
+static int pic64hpsc_mdio_c22_read(struct mii_bus *bus, int mii_id, int regnum)
+{
+	struct pic64hpsc_mdio_dev *priv = bus->priv;
+	u32 val;
+	int ret;
+
+	ret = pic64hpsc_mdio_wait_trigger(bus);
+	if (ret)
+		return ret;
+
+	writel(MDIO_TRIGGER_BIT | FIELD_PREP(MDIO_REG_DEV_ADDR_MASK, regnum) |
+		       FIELD_PREP(MDIO_PHY_PRT_ADDR_MASK, mii_id) |
+		       FIELD_PREP(MDIO_OPERATION_MASK, MDIO_OPERATION_READ) |
+		       FIELD_PREP(MDIO_START_OF_FRAME_MASK, 1),
+	       priv->regs + MDIO_REG_FRAME_CFG_2);
+
+	ret = pic64hpsc_mdio_wait_trigger(bus);
+	if (ret)
+		return ret;
+
+	val = readl(priv->regs + MDIO_REG_FRAME_STATUS);
+
+	/* The MDIO_READOK is a 1-bit value reflecting the inverse of the MDIO
+	 * bus value captured during the 2nd TA cycle. A PHY/Port should drive
+	 * the MDIO bus with a logic 0 on the 2nd TA cycle, however, the
+	 * PHY/Port could optionally drive a logic 1, to communicate a read
+	 * failure. This feature is optional, not defined by the 802.3 standard
+	 * and not supported in standard external PHYs.
+	 */
+	if (!(bus->phy_ignore_ta_mask & 1 << mii_id) &&
+	    !FIELD_GET(MDIO_READOK_BIT, val)) {
+		dev_dbg(&bus->dev, "READOK bit cleared\n");
+		return -EIO;
+	}
+
+	return FIELD_GET(MDIO_RDATA_MASK, val);
+}
+
+static int pic64hpsc_mdio_c22_write(struct mii_bus *bus, int mii_id, int regnum,
+				    u16 value)
+{
+	struct pic64hpsc_mdio_dev *priv = bus->priv;
+	int ret;
+
+	ret = pic64hpsc_mdio_wait_trigger(bus);
+	if (ret < 0)
+		return ret;
+
+	writel(FIELD_PREP(MDIO_WDATA_MASK, value),
+	       priv->regs + MDIO_REG_FRAME_CFG_1);
+
+	writel(MDIO_TRIGGER_BIT | FIELD_PREP(MDIO_REG_DEV_ADDR_MASK, regnum) |
+		       FIELD_PREP(MDIO_PHY_PRT_ADDR_MASK, mii_id) |
+		       FIELD_PREP(MDIO_OPERATION_MASK, MDIO_OPERATION_WRITE) |
+		       FIELD_PREP(MDIO_START_OF_FRAME_MASK, 1),
+	       priv->regs + MDIO_REG_FRAME_CFG_2);
+
+	return 0;
+}
+
+static int pic64hpsc_mdio_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct device *dev = &pdev->dev;
+	struct pic64hpsc_mdio_dev *priv;
+	struct mii_bus *bus;
+	unsigned long rate;
+	struct clk *clk;
+	u32 bus_freq;
+	u32 div;
+	int ret;
+
+	bus = devm_mdiobus_alloc_size(dev, sizeof(*priv));
+	if (!bus)
+		return -ENOMEM;
+
+	priv = bus->priv;
+
+	priv->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(priv->regs))
+		return PTR_ERR(priv->regs);
+
+	bus->name = KBUILD_MODNAME;
+	bus->read = pic64hpsc_mdio_c22_read;
+	bus->write = pic64hpsc_mdio_c22_write;
+	snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev));
+	bus->parent = dev;
+
+	clk = devm_clk_get_enabled(dev, NULL);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	if (of_property_read_u32(np, "clock-frequency", &bus_freq))
+		bus_freq = 2500000;
+
+	rate = clk_get_rate(clk);
+
+	div = DIV_ROUND_UP(rate, 2 * bus_freq) - 1;
+	if (div == 0 || div & ~MDIO_CFG_PRESCALE_MASK) {
+		dev_err(dev, "MDIO clock-frequency out of range\n");
+		return -EINVAL;
+	}
+
+	dev_dbg(dev, "rate=%lu bus_freq=%u real_bus_freq=%lu div=%u\n", rate,
+		bus_freq, rate / (2 * (1 + div)), div);
+	writel(div, priv->regs + MDIO_REG_PRESCALER);
+
+	ret = devm_of_mdiobus_register(dev, bus, np);
+	if (ret) {
+		dev_err(dev, "Cannot register MDIO bus (%d)\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct of_device_id pic64hpsc_mdio_match[] = {
+	{ .compatible = "microchip,pic64hpsc-mdio" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, pic64hpsc_mdio_match);
+
+static struct platform_driver pic64hpsc_mdio_driver = {
+	.probe = pic64hpsc_mdio_probe,
+	.driver = {
+		.name = KBUILD_MODNAME,
+		.of_match_table = pic64hpsc_mdio_match,
+	},
+};
+module_platform_driver(pic64hpsc_mdio_driver);
+
+MODULE_AUTHOR("Charles Perry <charles.perry@microchip.com>");
+MODULE_DESCRIPTION("Microchip PIC64-HPSC/HX MDIO driver");
+MODULE_LICENSE("GPL");
-- 
2.47.3


^ permalink raw reply related

* [PATCH net-next v4 0/3] Add support for PIC64-HPSC/HX MDIO controller
From: Charles Perry @ 2026-04-02 13:12 UTC (permalink / raw)
  To: netdev
  Cc: Charles Perry, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Heiner Kallweit, Russell King, devicetree

Hello,

This series adds a driver for the two MDIO controllers of PIC64-HPSC/HX.
The hardware supports C22 and C45 but only C22 is implemented for now.

This MDIO hardware is based on a Microsemi design supported in Linux by
mdio-mscc-miim.c. However, The register interface is completely different
with pic64hpsc, hence the need for a separate driver.

The documentation recommends an input clock of 156.25MHz and a prescaler of
39, which yields an MDIO clock of 1.95MHz.

This was tested on Microchip HB1301 evalkit which has a VSC8574 and a
VSC8541 with clock frequencies of 0.6, 1.95 and 2.5 MHz.

This series also adds a PHY write barrier when disabling PHY interrupts as
discussed in [1].

Thanks,
Charles

[1]: https://lore.kernel.org/all/acvUqDgepCIScs8M@shell.armlinux.org.uk/

Changes in v4:
- 3/3: Add the PHY barrier patch (Russell, Andrew)
- 2/3: return FIELD_GET() directly instead of using "ret" (Russell)

Changes in v3:
- 2/2: Add a MAINTAINERS entry (Jakub)

Changes in v2:
- 1/2: Make "clocks" and "interrupts" required (Andrew)
- 1/2: Add a default value to "clock-frequency" (Andrew)
- 2/2: Remove #define for unused registers (Maxime)
- 2/2: Add "c22" to clause 22 read/write ops (Maxime)
- 2/2: Remove the call to platform_set_drvdata() (Andrew)
- 2/2: Make the clock mandatory (Andrew)
- 2/2: Use 2.5MHz if no clock-frequency was specified (Andrew)
- 2/2: Change the error message for bad clock-frequency (Andrew)
- 2/2: Fix a use without initialization on bus_freq (Andrew)

CC: Andrew Lunn <andrew+netdev@lunn.ch>
CC: "David S. Miller" <davem@davemloft.net>
CC: Eric Dumazet <edumazet@google.com>
CC: Jakub Kicinski <kuba@kernel.org>
CC: Paolo Abeni <pabeni@redhat.com>
CC: Rob Herring <robh@kernel.org>
CC: Krzysztof Kozlowski <krzk+dt@kernel.org>
CC: Conor Dooley <conor+dt@kernel.org>
CC: Heiner Kallweit <hkallweit1@gmail.com>
CC: Russell King <linux@armlinux.org.uk>
CC: netdev@vger.kernel.org
CC: devicetree@vger.kernel.org

Charles Perry (3):
  dt-bindings: net: document Microchip PIC64-HPSC/HX MDIO controller
  net: mdio: add a driver for PIC64-HPSC/HX MDIO controller
  net: phy: add a PHY write barrier when disabling interrupts

 .../net/microchip,pic64hpsc-mdio.yaml         |  68 +++++++
 MAINTAINERS                                   |   6 +
 drivers/net/mdio/Kconfig                      |   7 +
 drivers/net/mdio/Makefile                     |   1 +
 drivers/net/mdio/mdio-pic64hpsc.c             | 190 ++++++++++++++++++
 drivers/net/phy/phy.c                         |  27 ++-
 6 files changed, 298 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/net/microchip,pic64hpsc-mdio.yaml
 create mode 100644 drivers/net/mdio/mdio-pic64hpsc.c

-- 
2.47.3


^ permalink raw reply

* Re: [RFC PATCH 2/4] nfs: add NFS_CAP_P2PDMA and detect transport support
From: Chuck Lever @ 2026-04-02 13:11 UTC (permalink / raw)
  To: Pranjal Shrivastava, Trond Myklebust, Anna Schumaker
  Cc: davem, Jakub Kicinski, edumazet, Paolo Abeni, Chuck Lever,
	Jeff Layton, Tom Talpey, Olga Kornievskaia, NeilBrown, Dai Ngo,
	linux-nfs, netdev
In-Reply-To: <20260401194501.2269200-3-praan@google.com>


On Wed, Apr 1, 2026, at 3:44 PM, Pranjal Shrivastava wrote:
> The NFS server capabilities bitmask (server->caps) is currently full,
> utilizing all 32 bits of the existing unsigned int. Expand the bitmask
> to 64 bits (u64) to allow for new feature flags.
>
> Introduce a new capability bit, NFS_CAP_P2PDMA, to indicate that the
> local mount is backed by hardware and a transport capable of PCI
> Peer-to-Peer DMA.
>
> Update nfs_server_set_init_caps() to query the underlying SunRPC
> transport for P2PDMA support during the mount process. If the transport
> (e.g., RDMA) signals support, set the NFS_CAP_P2PDMA bit in the mount's
> capabilities. This allows the high-performance Direct I/O path to
> efficiently determine if it should allow P2P memory buffers.

> diff --git a/fs/nfs/client.c b/fs/nfs/client.c
> index be02bb227741..f177cf098d44 100644
> --- a/fs/nfs/client.c
> +++ b/fs/nfs/client.c

> @@ -725,6 +727,12 @@ void nfs_server_set_init_caps(struct nfs_server *server)
>  		nfs4_server_set_init_caps(server);
>  		break;
>  	}
> +
> +	rcu_read_lock();
> +	xprt = rcu_dereference(server->client->cl_xprt);
> +	if (xprt->ops->supports_p2pdma && xprt->ops->supports_p2pdma(xprt))
> +		server->caps |= NFS_CAP_P2PDMA;
> +	rcu_read_unlock();
>  }
>  EXPORT_SYMBOL_GPL(nfs_server_set_init_caps);

Is the transport even connected when the NFS client does this
test? If it isn't, xprtrdma and the RDMA core have not chosen
an underlying device yet.

Note that, even if this logic /is/ correct, if the transport
connection is lost the transport will reconnect automatically,
doing the RDMA CM dance again and possibly resolving to a
different device. The NFS client layer will be none-the-wiser
and the NFS_CAP_P2PDMA flag setting will be stale at that point,
and quite possibly incorrect if the new connection's device is
not P2P-enabled.

(Basically this is what happens when an RDMA device is removed).

So this detection has to be done as part of xprtrdma's connection
flow, and it needs to set a flag somewhere in the rpc_xprt. The
NFS direct I/O code path then has to look for that flag before
choosing the mechanism/flags it uses for each iov iter.


-- 
Chuck Lever

^ permalink raw reply

* Re: [PATCH net 1/2] vsock/virtio: fix MSG_PEEK ignoring skb offset when calculating bytes to copy
From: Stefano Garzarella @ 2026-04-02 13:08 UTC (permalink / raw)
  To: Luigi Leonardi
  Cc: Stefan Hajnoczi, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
	Eugenio Pérez, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Arseniy Krasnov, kvm, virtualization,
	netdev, linux-kernel
In-Reply-To: <20260402-fix_peek-v1-1-ad274fcef77b@redhat.com>

On Thu, Apr 02, 2026 at 10:18:01AM +0200, Luigi Leonardi wrote:
>`virtio_transport_stream_do_peek()` does not account for the skb offset
>when computing the number of bytes to copy.
>
>This means that, after a partial recv() that advances the offset, a peek
>requesting more bytes than are available in the sk_buff causes
>`skb_copy_datagram_iter()` to go past the valid payload, resulting in a -EFAULT.

nit:

WARNING: Prefer a maximum 75 chars per line (possible unwrapped commit description?)
#14: `skb_copy_datagram_iter()` to go past the valid payload, resulting 
in a -EFAULT.

>
>The dequeue path already handles this correctly.
>Apply the same logic to the peek path.
>
>Fixes: 0df7cd3c13e4 ("vsock/virtio/vhost: read data from non-linear skb")
>Signed-off-by: Luigi Leonardi <leonardi@redhat.com>
>---
> net/vmw_vsock/virtio_transport_common.c | 5 ++---
> 1 file changed, 2 insertions(+), 3 deletions(-)
>
>diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
>index 8a9fb23c6e853dfea0a24d3787f7d6eb351dd6c6..4b65bfe5d875111f115e0fc4c6727adb66f34830 100644
>--- a/net/vmw_vsock/virtio_transport_common.c
>+++ b/net/vmw_vsock/virtio_transport_common.c
>@@ -547,9 +547,8 @@ virtio_transport_stream_do_peek(struct vsock_sock *vsk,
> 	skb_queue_walk(&vvs->rx_queue, skb) {
> 		size_t bytes;
>
>-		bytes = len - total;
>-		if (bytes > skb->len)
>-			bytes = skb->len;
>+		bytes = min_t(size_t, len - total,
>+			      skb->len - VIRTIO_VSOCK_SKB_CB(skb)->offset);

I think we should add some helper like virtio_transport_skb_remain() or 
virtio_transport_skb_bytes() and use it here but also in places where we 
check offset < len or offset == len. But maybe better to do that in 
another patch/series for net-next.

This fix LGTM:

Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>


^ permalink raw reply

* Re: [PATCH net-next v3 12/13] net: renesas: rswitch: add handler for FDB notification
From: Paolo Abeni @ 2026-04-02 13:06 UTC (permalink / raw)
  To: Michael Dege, Yoshihiro Shimoda, Andrew Lunn, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Niklas Söderlund, Paul Barker
  Cc: netdev, linux-renesas-soc, linux-kernel
In-Reply-To: <20260331-rswitch_add_vlans-v3-12-c37f41b1c556@renesas.com>

On 3/31/26 12:04 PM, Michael Dege wrote:
> +/* called under rcu_read_lock() */
> +static int rswitch_switchdev_event(struct notifier_block *nb,
> +				   unsigned long event,
> +				   void *ptr)
> +{
> +	struct net_device *ndev = switchdev_notifier_info_to_dev(ptr);
> +	struct rswitch_switchdev_event_work *switchdev_work;
> +	struct switchdev_notifier_fdb_info *fdb_info;
> +	struct switchdev_notifier_info *info = ptr;
> +	struct rswitch_private *priv;
> +	int err;
> +
> +	priv = container_of(nb, struct rswitch_private, rswitch_switchdev_nb);
> +
> +	switch (event) {
> +	case SWITCHDEV_FDB_ADD_TO_DEVICE:
> +		fallthrough;
> +	case SWITCHDEV_FDB_DEL_TO_DEVICE:
> +		switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC);
> +
> +		if (!switchdev_work)
> +			return NOTIFY_BAD;
> +
> +		switchdev_work->ndev = info->dev;
> +		switchdev_work->priv = priv;
> +		switchdev_work->event = event;
> +
> +		fdb_info = container_of(info,
> +					struct switchdev_notifier_fdb_info,
> +					info);
> +
> +		INIT_WORK(&switchdev_work->work, rswitch_switchdev_bridge_fdb_event_work);
> +
> +		memcpy(&switchdev_work->fdb_info, ptr, sizeof(switchdev_work->fdb_info));
> +
> +		switchdev_work->fdb_info.addr = kzalloc(ETH_ALEN, GFP_ATOMIC);
> +		if (!switchdev_work->fdb_info.addr)
> +			goto err_addr_alloc;
> +
> +		ether_addr_copy((u8 *)switchdev_work->fdb_info.addr,
> +				fdb_info->addr);
> +		dev_hold(ndev);

Please switch to netdev_hold()/netdev_put(), providing a suitable
netdevice_tracker.

/P


^ permalink raw reply

* Re: [PATCH net-next v3 04/13] net: renesas: rswitch: add register definitions for vlan support
From: Paolo Abeni @ 2026-04-02 13:02 UTC (permalink / raw)
  To: Michael Dege, Yoshihiro Shimoda, Andrew Lunn, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Niklas Söderlund, Paul Barker
  Cc: netdev, linux-renesas-soc, linux-kernel
In-Reply-To: <20260331-rswitch_add_vlans-v3-4-c37f41b1c556@renesas.com>

On 3/31/26 12:03 PM, Michael Dege wrote:
@@ -847,6 +903,98 @@ enum rswitch_gwca_mode {
>  #define FWMACAGC_MACAGOG	BIT(28)
>  #define FWMACAGC_MACDESOG	BIT(29)
>  
> +//FWMACTL0

Please always use /* */ for comments

/P


^ permalink raw reply

* Re: [PATCH] idpf: Replace use of system_unbound_wq with system_dfl_wq
From: Marco Crivellari @ 2026-04-02 13:02 UTC (permalink / raw)
  To: Przemek Kitszel
  Cc: intel-wired-lan, Tejun Heo, linux-kernel, netdev, Lai Jiangshan,
	Frederic Weisbecker, Sebastian Andrzej Siewior, Michal Hocko,
	Tony Nguyen, Andrew Lunn, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni
In-Reply-To: <0ca7f92b-ec4e-469c-ad2b-648d278bcfe9@intel.com>

On Fri, Mar 13, 2026 at 5:09 PM Przemek Kitszel
<przemyslaw.kitszel@intel.com> wrote:
> [...]
> this wording kinda scared me, but after reading linked commits, there is
> nothing to worry about, as there are no functional changes in this patch
>
> Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>

Hi,

Sorry for the late reply. Yes, correct: there are no functional changes.

Thanks!
-- 

Marco Crivellari

SUSE Labs

^ permalink raw reply

* Re: [net-next,v3,13/13] net: renesas: rswitch: add vlan aware switching
From: Paolo Abeni @ 2026-04-02 12:59 UTC (permalink / raw)
  To: michael.dege
  Cc: paul, niklas.soderlund, kuba, yoshihiro.shimoda.uh, netdev,
	linux-kernel, edumazet, pabeni, linux-renesas-soc, andrew+netdev,
	davem
In-Reply-To: <20260331-rswitch_add_vlans-v3-13-c37f41b1c556@renesas.com>

This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.

For local reproduction steps see https://netdev-ai.bots.linux.dev/ai-local.html
---
net: renesas: rswitch: add vlan aware switching

This commit adds vlan support to the L2 HW bridge, with limited support
on R-Car S4 (not fully 802.1Q compliant).

> diff --git a/drivers/net/ethernet/renesas/Kconfig b/drivers/net/ethernet/renesas/Kconfig
> index 9b7559c88bee..2494ff60e8c2 100644
> --- a/drivers/net/ethernet/renesas/Kconfig
> +++ b/drivers/net/ethernet/renesas/Kconfig

[ ... ]

> diff --git a/drivers/net/ethernet/renesas/rswitch_l2.c b/drivers/net/ethernet/renesas/rswitch_l2.c
> index ea95a87ed234..b7d0e7f94ecd 100644
> --- a/drivers/net/ethernet/renesas/rswitch_l2.c
> +++ b/drivers/net/ethernet/renesas/rswitch_l2.c

[ ... ]

> @@ -212,61 +197,397 @@ static int rswitch_netdevice_event(struct notifier_block *nb,

[ ... ]

> +static int rswitch_handle_port_obj_add(struct net_device *ndev,
> +				       struct notifier_block *nb,
> +				       struct switchdev_notifier_port_obj_info *info)
> +{
> +	struct switchdev_obj_port_vlan *p_vlan = SWITCHDEV_OBJ_PORT_VLAN(info->obj);
> +	struct rswitch_private *priv;
> +	int err;
> +
> +	priv = container_of(nb, struct rswitch_private, rswitch_switchdev_blocking_nb);
> +
> +	if ((p_vlan->flags & BRIDGE_VLAN_INFO_MASTER) ||
> +	    (p_vlan->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) ||
> +	    (p_vlan->flags & BRIDGE_VLAN_INFO_RANGE_END) ||
> +	    (p_vlan->flags & BRIDGE_VLAN_INFO_ONLY_OPTS))
> +		return NOTIFY_DONE;
> +
> +	switch (info->obj->id) {
> +	case SWITCHDEV_OBJ_ID_PORT_VLAN:

Can the flag checks access the wrong memory? The code casts info->obj to
switchdev_obj_port_vlan before checking info->obj->id. When the notifier
delivers a non-VLAN object (such as SWITCHDEV_OBJ_ID_PORT_MDB for multicast
group changes), SWITCHDEV_OBJ_PORT_VLAN() performs an incorrect container_of
cast, and p_vlan->flags reads bytes from a different struct type.

For switchdev_obj_port_mdb, the p_vlan->flags field overlaps with the first
2 bytes of the addr[ETH_ALEN] MAC address field. Multicast MAC addresses
always have bit 0 of the first byte set, which matches BRIDGE_VLAN_INFO_MASTER
(1<<0), causing the function to return NOTIFY_DONE instead of falling through
to the default case that returns -EOPNOTSUPP.

Other switchdev drivers (lan966x, mlxsw, cpsw) perform the
SWITCHDEV_OBJ_PORT_VLAN cast inside the SWITCHDEV_OBJ_ID_PORT_VLAN case,
not before the type switch.

The same issue exists in rswitch_handle_port_obj_del().

> +		if (!is_rdev(ndev))
> +			err = rswitch_port_obj_do_add_gwca(ndev, priv, p_vlan);
> +		else
> +			err = rswitch_port_obj_do_add(ndev, p_vlan);
> +
> +		if (err < 0)
> +			return err;
> +
> +		break;
> +	default:
> +		return -EOPNOTSUPP;
> +	}
> +
> +	info->handled = true;
> +
> +	return NOTIFY_DONE;
> +}
> +
> +static int rswitch_handle_port_obj_del(struct net_device *ndev,
> +				       struct notifier_block *nb,
> +				       struct switchdev_notifier_port_obj_info *info)
> +{
> +	struct switchdev_obj_port_vlan *p_vlan = SWITCHDEV_OBJ_PORT_VLAN(info->obj);
> +	struct rswitch_private *priv;
> +	int err;
> +
> +	priv = container_of(nb, struct rswitch_private, rswitch_switchdev_blocking_nb);
> +
> +	if ((p_vlan->flags & BRIDGE_VLAN_INFO_MASTER) ||
> +	    (p_vlan->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) ||
> +	    (p_vlan->flags & BRIDGE_VLAN_INFO_RANGE_END) ||
> +	    (p_vlan->flags & BRIDGE_VLAN_INFO_ONLY_OPTS))
> +		return NOTIFY_DONE;
> +
> +	switch (info->obj->id) {
> +	case SWITCHDEV_OBJ_ID_PORT_VLAN:
> +		if (!is_rdev(ndev))
> +			err = rswitch_port_obj_do_del_gwca(ndev, priv, p_vlan);
> +		else
> +			err = rswitch_port_obj_do_del(ndev, p_vlan);
> +
> +		if (err < 0)
> +			return err;
> +
> +		break;
> +	default:
> +		return -EOPNOTSUPP;
> +	}
> +
> +	info->handled = true;
> +
> +	return NOTIFY_DONE;
> +}

[ ... ]


^ permalink raw reply

* Re: [net-next,v3,12/13] net: renesas: rswitch: add handler for FDB notification
From: Paolo Abeni @ 2026-04-02 12:59 UTC (permalink / raw)
  To: michael.dege
  Cc: paul, niklas.soderlund, kuba, yoshihiro.shimoda.uh, netdev,
	linux-kernel, edumazet, pabeni, linux-renesas-soc, andrew+netdev,
	davem
In-Reply-To: <20260331-rswitch_add_vlans-v3-12-c37f41b1c556@renesas.com>

This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.

For local reproduction steps see https://netdev-ai.bots.linux.dev/ai-local.html
---
net: renesas: rswitch: add handler for FDB notification

The SWITCHDEV_FDB_ADD_TO_DEVICE notification writes the bridge MAC
address to the GWCA and adds a static rule to the MAC table. The
SWITCHDEV_FDB_DEL_TO_DEVICE removes the static rule from the MAC table.

> diff --git a/drivers/net/ethernet/renesas/rswitch.h b/drivers/net/ethernet/renesas/rswitch.h
> index 6dfc53c6b985..443fc4e49602 100644
> --- a/drivers/net/ethernet/renesas/rswitch.h
> +++ b/drivers/net/ethernet/renesas/rswitch.h

[ ... ]

> diff --git a/drivers/net/ethernet/renesas/rswitch_l2.c b/drivers/net/ethernet/renesas/rswitch_l2.c
> index f1c5c96027ba..ea95a87ed234 100644
> --- a/drivers/net/ethernet/renesas/rswitch_l2.c
> +++ b/drivers/net/ethernet/renesas/rswitch_l2.c

[ ... ]

> @@ -285,6 +269,181 @@ static int rswitch_switchdev_blocking_event(struct notifier_block *nb,
>  	return notifier_from_errno(ret);
>  }
>
> +static int rswitch_gwca_write_mac_address(struct rswitch_private *priv, const u8 *mac)
> +{
> +	int err;
> +
> +	err = rswitch_gwca_change_mode(priv, GWMC_OPC_CONFIG);
> +	if (err < 0)
> +		return err;
> +
> +	iowrite32((mac[0] << 8) | mac[1], priv->addr + GWMAC0);
> +	iowrite32((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5],
> +		  priv->addr + GWMAC1);
> +
> +	return rswitch_gwca_change_mode(priv, GWMC_OPC_OPERATION);
> +}
> +
> +static int rswitch_add_addr_to_mactable(struct rswitch_private *priv, const u8 *mac)
> +{
> +	u32 index = priv->gwca.l2_shared_rx_queue->index;
> +	int err;
> +
> +	rswitch_modify(priv->addr, FWMACTL0, FWMACTL0_ED, 0);
> +	iowrite32((mac[0] << 8) | mac[1], priv->addr + FWMACTL1);
> +	iowrite32((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5],
> +		  priv->addr + FWMACTL2);
> +	iowrite32(FWMACTL3_DSLV | FWMACTL3_SSLV,
> +		  priv->addr + FWMACTL3);
> +	iowrite32(FIELD_PREP(FWMACTL4_CSDL, index),
> +		  priv->addr + FWMACTL4(GWCA_INDEX));
> +	iowrite32(FIELD_PREP(FWMACTL5_DV, BIT(AGENT_INDEX_GWCA)),
> +		  priv->addr + FWMACTL5);
> +
> +	err = rswitch_reg_wait(priv->addr, FWMACTLR, FWMACTLR_L, 0);
> +	if (err < 0)
> +		return err;
> +
> +	if (ioread32(priv->addr + FWMACTLR))
> +		return NOTIFY_BAD;
> +
> +	return NOTIFY_DONE;
> +}
> +
> +static int rswitch_del_addr_from_mactable(struct rswitch_private *priv, const u8 *mac)
> +{
> +	int err;
> +
> +	rswitch_modify(priv->addr, FWMACTL0, 0, FWMACTL0_ED);
> +	iowrite32((mac[0] << 8) | mac[1], priv->addr + FWMACTL1);
> +	iowrite32((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5],
> +		  priv->addr + FWMACTL2);
> +	iowrite32(FWMACTL3_DSLV | FWMACTL3_SSLV,
> +		  priv->addr + FWMACTL3);
> +	iowrite32(FIELD_PREP(FWMACTL4_CSDL, BIT(0)),
> +		  priv->addr + FWMACTL4(GWCA_INDEX));
> +	iowrite32(FIELD_PREP(FWMACTL5_DV, BIT(AGENT_INDEX_GWCA)),
> +		  priv->addr + FWMACTL5);
> +
> +	err = rswitch_reg_wait(priv->addr, FWMACTLR, FWMACTLR_L, 0);
> +	if (err < 0)
> +		return err;
> +
> +	err = ioread32(priv->addr + FWMACTLR);
> +	if (err)
> +		return NOTIFY_BAD;
> +
> +	return NOTIFY_DONE;
> +}
> +
> +static void rswitch_switchdev_bridge_fdb_event_work(struct work_struct *work)
> +{
> +	struct rswitch_switchdev_event_work *switchdev_work;
> +	struct rswitch_device *rdev;
> +	struct net_device *ndev;
> +
> +	switchdev_work = container_of(work, struct rswitch_switchdev_event_work, work);
> +	ndev = switchdev_work->ndev;
> +
> +	rtnl_lock();
> +
> +	/* Unfortunately all net_device members point to br0, there is no simple way to check
> +	 * if the event was triggered by a port device setting.
> +	 */
> +	rswitch_for_all_ports(switchdev_work->priv, rdev) {
> +		if (ether_addr_equal(rdev->ndev->dev_addr, switchdev_work->fdb_info.addr))
> +			goto out;
> +	}
> +
> +	/* Handle only bridge device */
> +	if (is_rdev(ndev))
> +		goto out;
> +
> +	switch (switchdev_work->event) {
> +	case SWITCHDEV_FDB_ADD_TO_DEVICE:
> +		rswitch_gwca_write_mac_address(switchdev_work->priv, switchdev_work->fdb_info.addr);
> +		rswitch_add_addr_to_mactable(switchdev_work->priv, switchdev_work->fdb_info.addr);
> +		break;
> +	case SWITCHDEV_FDB_DEL_TO_DEVICE:
> +		rswitch_del_addr_from_mactable(switchdev_work->priv, switchdev_work->fdb_info.addr);
> +		break;
> +	default:
> +		break;
> +	}
> +
> +out:
> +	rtnl_unlock();
> +
> +	kfree(switchdev_work->fdb_info.addr);
> +	kfree(switchdev_work);
> +	dev_put(ndev);
> +}
> +
> +/* called under rcu_read_lock() */
> +static int rswitch_switchdev_event(struct notifier_block *nb,
> +				   unsigned long event,
> +				   void *ptr)
> +{
> +	struct net_device *ndev = switchdev_notifier_info_to_dev(ptr);
> +	struct rswitch_switchdev_event_work *switchdev_work;
> +	struct switchdev_notifier_fdb_info *fdb_info;
> +	struct switchdev_notifier_info *info = ptr;
> +	struct rswitch_private *priv;
> +	int err;
> +
> +	priv = container_of(nb, struct rswitch_private, rswitch_switchdev_nb);
> +
> +	switch (event) {
> +	case SWITCHDEV_FDB_ADD_TO_DEVICE:
> +		fallthrough;
> +	case SWITCHDEV_FDB_DEL_TO_DEVICE:
> +		switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC);
> +
> +		if (!switchdev_work)
> +			return NOTIFY_BAD;
> +
> +		switchdev_work->ndev = info->dev;
> +		switchdev_work->priv = priv;
> +		switchdev_work->event = event;
> +
> +		fdb_info = container_of(info,
> +					struct switchdev_notifier_fdb_info,
> +					info);
> +
> +		INIT_WORK(&switchdev_work->work, rswitch_switchdev_bridge_fdb_event_work);
> +
> +		memcpy(&switchdev_work->fdb_info, ptr, sizeof(switchdev_work->fdb_info));
> +
> +		switchdev_work->fdb_info.addr = kzalloc(ETH_ALEN, GFP_ATOMIC);
> +		if (!switchdev_work->fdb_info.addr)
> +			goto err_addr_alloc;
> +
> +		ether_addr_copy((u8 *)switchdev_work->fdb_info.addr,
> +				fdb_info->addr);
> +		dev_hold(ndev);
> +		queue_work(system_long_wq, &switchdev_work->work);
> +
> +		break;
> +	case SWITCHDEV_PORT_ATTR_SET:
> +		err = switchdev_handle_port_attr_set(ndev, ptr,
> +						     is_rdev,
> +						     rswitch_port_attr_set);
> +		return notifier_from_errno(err);
> +
> +		if (!is_rdev(ndev))
> +			return NOTIFY_DONE;
> +
> +		return notifier_from_errno(-EOPNOTSUPP);

Are these lines in the SWITCHDEV_PORT_ATTR_SET case reachable? The
return notifier_from_errno(err) above them looks like it returns
unconditionally.

Note: this dead code is removed in the next commit in the series
(ed3ab4a0a727 'net: renesas: rswitch: add vlan aware switching'),
which moves PORT_ATTR_SET handling to rswitch_switchdev_blocking_event
and removes this entire case from rswitch_switchdev_event.

> +	}
> +
> +	return NOTIFY_DONE;
> +
> +err_addr_alloc:
> +	kfree(switchdev_work);
> +
> +	return NOTIFY_BAD;
> +}
> +
>  int rswitch_register_notifiers(struct rswitch_private *priv)
>  {
>  	int err;


^ permalink raw reply

* Re: [net-next,v3,06/13] net: renesas: rswitch: add forwarding rules for gwca
From: Paolo Abeni @ 2026-04-02 12:59 UTC (permalink / raw)
  To: michael.dege
  Cc: paul, niklas.soderlund, kuba, yoshihiro.shimoda.uh, netdev,
	linux-kernel, edumazet, pabeni, linux-renesas-soc, andrew+netdev,
	davem
In-Reply-To: <20260331-rswitch_add_vlans-v3-6-c37f41b1c556@renesas.com>

This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.

For local reproduction steps see https://netdev-ai.bots.linux.dev/ai-local.html
---
net: renesas: rswitch: add forwarding rules for gwca

Add rules to forward packets from the Ethernet ports to the CPU port (GWCA)
using L2 forwarding instead of port forwarding.

> diff --git a/drivers/net/ethernet/renesas/rswitch_l2.c b/drivers/net/ethernet/renesas/rswitch_l2.c
> index 709524c8a5c4..cabf1f92ad0c 100644
> --- a/drivers/net/ethernet/renesas/rswitch_l2.c
> +++ b/drivers/net/ethernet/renesas/rswitch_l2.c
> @@ -93,10 +93,32 @@ static void rswitch_update_l2_hw_forwarding(struct rswitch_private *priv)
>  	}
>  }
>
> +static void rswitch_update_l2_hw_forwarding_gwca(struct rswitch_private *priv)
> +{
> +	struct rswitch_device *rdev;
> +	u32 fwpc0_set, fwpc0_clr, fwpc2_set, fwpc2_clr;
> +
> +	fwpc0_clr = FWPC0_MACSSA | FWPC0_MACDSA | FWPC0_MACRUDA;
> +	fwpc0_set = fwpc0_clr;
> +	fwpc2_clr = FIELD_PREP(FWPC2_LTWFW, BIT(AGENT_INDEX_GWCA));
> +	fwpc2_set = fwpc2_clr;
> +
> +	(priv->offload_brdev) ? (fwpc0_clr = 0, fwpc2_set = 0)
> +			      : (fwpc0_set = 0, fwpc2_set = 0);
>                                             ^^^^^^^^^^^

Does the false branch have a copy-paste error? Looking at the ternary
operator:

The TRUE branch (when offload_brdev is set) assigns:
    fwpc0_clr = 0
    fwpc2_set = 0

The FALSE branch (when offload_brdev is NULL) assigns:
    fwpc0_set = 0
    fwpc2_set = 0   <- assigns to fwpc2_set

Both branches assign to fwpc2_set, leaving fwpc2_clr unchanged with the
initialized value FIELD_PREP(FWPC2_LTWFW, BIT(AGENT_INDEX_GWCA)).

This appears to break the logic for non-offloaded mode. The FALSE branch
passes fwpc2_clr with the GWCA bit set to rswitch_modify(), which clears
the GWCA bit from the FWPC2 registers. Is this the intended behavior when
bridge offload is disabled?

The symmetric pattern in the TRUE branch suggests the FALSE branch should
be (fwpc0_set = 0, fwpc2_clr = 0) instead.

> +
> +	rswitch_modify(priv->addr, FWPC0(AGENT_INDEX_GWCA), fwpc0_clr, fwpc0_set);
> +
> +	rswitch_for_all_ports(priv, rdev) {
> +		rswitch_modify(priv->addr, FWPC2(rdev->etha->index),
> +			       fwpc2_clr, fwpc2_set);
> +	}
> +}
> +
>  void rswitch_update_l2_offload(struct rswitch_private *priv)
>  {
>  	rswitch_update_l2_hw_learning(priv);
>  	rswitch_update_l2_hw_forwarding(priv);
> +	rswitch_update_l2_hw_forwarding_gwca(priv);
>  }

[ ... ]


^ permalink raw reply

* Re: [net-next,v3,05/13] net: renesas: rswitch: add exception path for packets with unknown dst MAC
From: Paolo Abeni @ 2026-04-02 12:59 UTC (permalink / raw)
  To: michael.dege
  Cc: paul, niklas.soderlund, kuba, yoshihiro.shimoda.uh, netdev,
	linux-kernel, edumazet, pabeni, linux-renesas-soc, andrew+netdev,
	davem
In-Reply-To: <20260331-rswitch_add_vlans-v3-5-c37f41b1c556@renesas.com>

This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.

For local reproduction steps see https://netdev-ai.bots.linux.dev/ai-local.html
---
net: renesas: rswitch: add exception path for packets with unknown dst MAC

This commit creates a shared RX queue for the exception path to handle
packets with unknown MAC addresses that cannot be processed by HW
forwarding. The queue receives packets with unknown src/dst addresses
and forwards them to the CPU for MAC learning.

> diff --git a/drivers/net/ethernet/renesas/rswitch.h b/drivers/net/ethernet/renesas/rswitch.h
> index 15d3fa48b0e3..bf123b564ed1 100644
> --- a/drivers/net/ethernet/renesas/rswitch.h
> +++ b/drivers/net/ethernet/renesas/rswitch.h
> @@ -1148,6 +1148,7 @@ struct rswitch_gwca {
>  	struct rswitch_gwca_queue *queues;
>  	int num_queues;
>  	struct rswitch_gwca_queue ts_queue;
> +	struct rswitch_gwca_queue *l2_shared_rx_queue;
>  	DECLARE_BITMAP(used, RSWITCH_MAX_NUM_QUEUES);
>  	u32 tx_irq_bits[RSWITCH_NUM_IRQ_REGS];
>  	u32 rx_irq_bits[RSWITCH_NUM_IRQ_REGS];
> diff --git a/drivers/net/ethernet/renesas/rswitch_main.c b/drivers/net/ethernet/renesas/rswitch_main.c
> index d404bc41bd1e..3c142fa3c810 100644
> --- a/drivers/net/ethernet/renesas/rswitch_main.c
> +++ b/drivers/net/ethernet/renesas/rswitch_main.c
> @@ -680,6 +680,34 @@ static int rswitch_rxdmac_init(struct rswitch_private *priv, unsigned int index)
>  	return rswitch_gwca_queue_ext_ts_format(ndev->dev.parent, priv, rdev->rx_queue);
>  }
>
> +static int rswitch_shared_rx_queue_alloc(struct rswitch_private *priv)
> +{
> +	struct rswitch_gwca *gwca = &priv->gwca;
> +	struct device *dev = &priv->pdev->dev;
> +
> +	int err;
> +
> +	gwca->l2_shared_rx_queue = rswitch_gwca_get(priv);
> +	if (!gwca->l2_shared_rx_queue)
> +		return -EBUSY;
> +
> +	err = rswitch_gwca_queue_alloc(NULL, priv, gwca->l2_shared_rx_queue, false, RX_RING_SIZE);
> +	if (err < 0) {
> +		rswitch_gwca_put(priv, gwca->l2_shared_rx_queue);
> +		return err;
> +	}
> +
> +	return rswitch_gwca_queue_ext_ts_format(dev, priv, gwca->l2_shared_rx_queue);
> +}
> +
> +static void rswitch_shared_rx_queue_free(struct rswitch_private *priv)
> +{
> +	struct rswitch_gwca *gwca = &priv->gwca;
> +
> +	rswitch_gwca_queue_free(&priv->pdev->dev, gwca->l2_shared_rx_queue);
> +	rswitch_gwca_put(priv, gwca->l2_shared_rx_queue);
> +}
> +
>  static int rswitch_gwca_hw_init(struct rswitch_private *priv)
>  {
>  	unsigned int i;
> @@ -717,6 +745,12 @@ static int rswitch_gwca_hw_init(struct rswitch_private *priv)
>  			return err;
>  	}
>
> +	err = rswitch_shared_rx_queue_alloc(priv);
> +	if (err < 0) {
> +		rswitch_shared_rx_queue_free(priv);
> +		return err;
> +	}

Does this cause a NULL pointer dereference if rswitch_shared_rx_queue_alloc()
fails? When rswitch_gwca_queue_alloc() fails internally (e.g., under memory
pressure during netdev_alloc_frag()), the 'out:' label inside
rswitch_gwca_queue_alloc() already calls rswitch_gwca_queue_free(), which sets
gq->rx_bufs = NULL and gq->rx_ring = NULL.

Then rswitch_shared_rx_queue_alloc() calls rswitch_gwca_put() and returns
error. The caller rswitch_gwca_hw_init() then calls
rswitch_shared_rx_queue_free(), which calls rswitch_gwca_queue_free() a second
time.

In this second call, gq->rx_bufs is NULL but gq->ring_size is still
RX_RING_SIZE, so the loop in rswitch_gwca_queue_free():

    for (i = 0; i < gq->ring_size; i++)
        skb_free_frag(gq->rx_bufs[i])

dereferences NULL (gq->rx_bufs[i] = NULL[i]). This causes a kernel NULL
pointer dereference crash during device probe under memory pressure.

Should the cleanup not call rswitch_shared_rx_queue_free() when
rswitch_shared_rx_queue_alloc() fails, since the alloc function already
performs partial cleanup internally?

> +
>  	return rswitch_gwca_change_mode(priv, GWMC_OPC_OPERATION);
>  }

[ ... ]

> @@ -1513,6 +1564,14 @@ static int rswitch_serdes_set_params(struct rswitch_device *rdev)
>  	return phy_set_speed(rdev->serdes, rdev->etha->speed);
>  }
>
> +static void rswitch_etha_set_exception_path(struct rswitch_private *priv)
> +{
> +	iowrite32(FDMACUFEF, priv->addr + FWCEPRC2);
> +	iowrite32(FIELD_PREP(EPCS, GWCA_INDEX) |
> +		  FIELD_PREP(EPCSD, priv->gwca.l2_shared_rx_queue->index),
> +		  priv->addr + FWCEPTC);
> +}
> +

[ ... ]

Looking at rswitch_init() in the existing code:

    err = rswitch_gwca_hw_init(priv);
    if (err)
        goto err_gwca_hw_init;

    err = rswitch_ether_port_init_all(priv);
    if (err)
        goto err_ether_port_init_all;

    err_ether_port_init_all:
        rswitch_gwca_hw_deinit(priv);

    err_gwca_hw_init:

When rswitch_gwca_hw_init() succeeds (allocating the shared RX queue via
rswitch_shared_rx_queue_alloc()), but a subsequent initialization step fails
(e.g., rswitch_ether_port_init_all() or register_netdev()), does the error
path leak the shared RX queue?

The error path at 'err_ether_port_init_all:' only calls
rswitch_gwca_hw_deinit(), which merely changes the GWCA hardware mode. It does
NOT call rswitch_shared_rx_queue_free() to release the DMA memory
(dma_alloc_coherent), rx_bufs (kzalloc), and page fragments allocated by
rswitch_shared_rx_queue_alloc(). These are not device-managed allocations.

Should the cleanup call rswitch_shared_rx_queue_free() before or after
rswitch_gwca_hw_deinit()?

[ ... ]

> @@ -952,15 +987,31 @@ static int rswitch_poll(struct napi_struct *napi, int budget)
>  	return 0;
>  }
>
> -static void rswitch_queue_interrupt(struct net_device *ndev)
> +static void rswitch_queue_interrupt(struct rswitch_private *priv, struct rswitch_gwca_queue *gq)
>  {
> -	struct rswitch_device *rdev = netdev_priv(ndev);
> +	struct rswitch_ext_ts_desc *desc;
> +	struct rswitch_device *rdev;
> +	struct net_device *ndev;
> +	u32 spn;
> +
> +	if (gq->index == priv->gwca.l2_shared_rx_queue->index) {
> +		desc = &gq->rx_ring[gq->cur];
> +		spn = FIELD_GET(SPN, desc->info1);
> +		ndev = priv->rdev[spn]->ndev;
> +		rdev = netdev_priv(ndev);
> +		gq->ndev = ndev;
> +		rdev->rx_queue = gq;

Can this permanently break per-port RX processing? When a shared RX queue
interrupt fires for a port, rswitch_queue_interrupt() overwrites
rdev->rx_queue to point to the shared queue (gq) instead of the port's
per-port RX queue. This assignment is never reversed. After this point:

(1) rswitch_poll() -> rswitch_rx() processes from rdev->rx_queue which now
points to the shared queue, so the per-port RX queue is never drained.

(2) When NAPI completes in rswitch_poll(), it re-enables rdev->rx_queue->index
(the shared queue index) instead of the original per-port RX queue index.

(3) The per-port RX queue IRQ is never re-enabled by NAPI completion
(rswitch_enadis_data_irq only re-enables rdev->rx_queue->index and
l2_shared_rx_queue->index, which are now the same):

rswitch_poll():
    if (napi_complete_done(napi, budget - quota)) {
        spin_lock_irqsave(&priv->lock, flags);
        rswitch_enadis_data_irq(priv, rdev->tx_queue->index, true);
        rswitch_enadis_data_irq(priv, rdev->rx_queue->index, true);
        rswitch_enadis_data_irq(priv, priv->gwca.l2_shared_rx_queue->index, true);
        ...
    }

This means the per-port RX queue becomes permanently orphaned after the first
shared-queue packet for that port, causing packet loss for all regular
(non-exception-path) traffic on that port.

Should the code save and restore the original rdev->rx_queue, or use a
separate mechanism to process shared queue packets without overwriting the
per-port queue pointer?

> +	} else {
> +		rdev = netdev_priv(gq->ndev);
> +	}
> +
> +
> +	if (napi_schedule_prep(&rdev->napi)) {
> +		spin_lock(&priv->lock);
> +		rswitch_enadis_data_irq(priv, rdev->tx_queue->index, false);
> +		rswitch_enadis_data_irq(priv, rdev->rx_queue->index, false);
> +		rswitch_enadis_data_irq(priv, priv->gwca.l2_shared_rx_queue->index, false);
> +		spin_unlock(&priv->lock);
>  		__napi_schedule(&rdev->napi);
>  	}
>  }

[ ... ]


^ permalink raw reply

* Re: [net-next,v3,04/13] net: renesas: rswitch: add register definitions for vlan support
From: Paolo Abeni @ 2026-04-02 12:59 UTC (permalink / raw)
  To: michael.dege
  Cc: paul, niklas.soderlund, kuba, yoshihiro.shimoda.uh, netdev,
	linux-kernel, edumazet, pabeni, linux-renesas-soc, andrew+netdev,
	davem
In-Reply-To: <20260331-rswitch_add_vlans-v3-4-c37f41b1c556@renesas.com>

This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.

For local reproduction steps see https://netdev-ai.bots.linux.dev/ai-local.html
---
net: renesas: rswitch: add register definitions for vlan support

This commit adds missing register and bit definitions for vlan support
in the Renesas R-Switch driver.

> diff --git a/drivers/net/ethernet/renesas/rswitch.h b/drivers/net/ethernet/renesas/rswitch.h
> index 340524d995ac..15d3fa48b0e3 100644
> --- a/drivers/net/ethernet/renesas/rswitch.h
> +++ b/drivers/net/ethernet/renesas/rswitch.h

[ ... ]

> @@ -847,6 +903,98 @@ enum rswitch_gwca_mode {
>  #define FWMACAGC_MACAGOG	BIT(28)
>  #define FWMACAGC_MACDESOG	BIT(29)
>
> +//FWMACTL0

[ ... ]

> +// FWVLANTEM
> +#define VLANTUEN		GENMASK(28, 16)
> +#define VLANTEN			GENAMSK(12, 0)
                                ^^^^^^^^

Is GENAMSK a typo? The correct macro is GENMASK, as used on the line
immediately above for VLANTUEN. GENAMSK is not defined in the kernel and
will cause compilation errors if VLANTEN is used.

> +
> +// FWVLANTS

[ ... ]


^ permalink raw reply

* Re: [PATCH net v2] ipvs: fix MTU check for GSO packets in tunnel mode
From: Julian Anastasov @ 2026-04-02 12:59 UTC (permalink / raw)
  To: Yingnan Zhang
  Cc: horms, pablo, fw, phil, davem, edumazet, kuba, pabeni, netdev,
	lvs-devel, netfilter-devel, coreteam, linux-kernel
In-Reply-To: <tencent_CA2C1C219C99D315086BE55E8654AF7E6009@qq.com>


	Hello,

On Thu, 2 Apr 2026, Yingnan Zhang wrote:

> Currently, IPVS skips MTU checks for GSO packets by excluding them with
> the !skb_is_gso(skb) condition in both IPv4 and IPv6 code paths. This
> creates problems when IPVS tunnel mode encapsulates GSO packets with
> IPIP or IPv6 tunnel headers.
> 
> The issue manifests in two ways:
> 
> 1. MTU violation after encapsulation:
>    When a GSO packet passes through IPVS tunnel mode, the original MTU
>    check is bypassed. After adding the tunnel header, the packet size
>    may exceed the outgoing interface MTU, leading to unexpected
>    fragmentation at the IP layer.
> 
> 2. Fragmentation with problematic IP IDs:
>    When net.ipv4.vs.pmtu_disc=1 and a GSO packet with multiple segments
>    is fragmented after encapsulation, each segment gets a sequentially
>    incremented IP ID (0, 1, 2, ...). This happens because:
> 
>    a) The GSO packet bypasses MTU check and gets encapsulated
>    b) At __ip_finish_output, the oversized GSO packet is split into
>       separate SKBs (one per segment), with IP IDs incrementing
>    c) Each SKB is then fragmented again based on the actual MTU
> 
>    This sequential IP ID allocation differs from the expected behavior
>    and can cause issues with fragment reassembly and packet tracking.
> 
> Fix this by removing the GSO packet exception from the MTU check in both
> IPv4 and IPv6 paths, and properly validating GSO packets using
> skb_gso_validate_network_len(). The condition is refactored to avoid
> code duplication.
> 
> Fixes: 4cdd34084d53 ("netfilter: nf_conntrack_ipv6: improve fragmentation handling")
> Signed-off-by: Yingnan Zhang <342144303@qq.com>
> ---
> Changes in v2:
> - Added IPv6 fix in __mtu_check_toobig_v6() per Julian's review
> - Refactored to avoid code duplication per Julian's suggestion
> - Applied same validation pattern to both IPv4 and IPv6 paths
> 
> v1: https://lore.kernel.org/netdev/20260401152228.31190-1-342144303@qq.com/
> 
>  net/netfilter/ipvs/ip_vs_xmit.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
> index 3601eb86d..ac2ad7518 100644
> --- a/net/netfilter/ipvs/ip_vs_xmit.c
> +++ b/net/netfilter/ipvs/ip_vs_xmit.c
> @@ -112,7 +112,8 @@ __mtu_check_toobig_v6(const struct sk_buff *skb, u32 mtu)
>  		if (IP6CB(skb)->frag_max_size > mtu)
>  			return true; /* largest fragment violate MTU */
>  	}

	You should remove the above line because compilation fails...

> -	else if (skb->len > mtu && !skb_is_gso(skb)) {
> +	} else if (skb->len > mtu &&
> +		   !(skb_is_gso(skb) && skb_gso_validate_network_len(skb, mtu))) {
>  		return true; /* Packet size violate MTU size */
>  	}
>  	return false;
> @@ -232,8 +233,9 @@ static inline bool ensure_mtu_is_adequate(struct netns_ipvs *ipvs, int skb_af,
>  			return true;
>  
>  		if (unlikely(ip_hdr(skb)->frag_off & htons(IP_DF) &&
> -			     skb->len > mtu && !skb_is_gso(skb) &&
> -			     !ip_vs_iph_icmp(ipvsh))) {
> +		     skb->len > mtu && !ip_vs_iph_icmp(ipvsh) &&
> +		     !(skb_is_gso(skb) &&
> +		       skb_gso_validate_network_len(skb, mtu)))) {

	Please keep the indentation, just like in my example

>  			icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
>  				  htonl(mtu));
>  			IP_VS_DBG(1, "frag needed for %pI4\n",
> -- 
> 2.51.0

Regards

--
Julian Anastasov <ja@ssi.bg>


^ permalink raw reply

* Re: [net-next,v3,01/13] net: renesas: rswitch: improve port change mode functions
From: Paolo Abeni @ 2026-04-02 12:59 UTC (permalink / raw)
  To: michael.dege
  Cc: paul, niklas.soderlund, kuba, yoshihiro.shimoda.uh, netdev,
	linux-kernel, edumazet, pabeni, linux-renesas-soc, andrew+netdev,
	davem
In-Reply-To: <20260331-rswitch_add_vlans-v3-1-c37f41b1c556@renesas.com>

This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.

For local reproduction steps see https://netdev-ai.bots.linux.dev/ai-local.html
---
net: renesas: rswitch: improve port change mode functions

For ETHA and GWCA ports every mode change from operational to
configuration and vice-versa requires to change the mode to "disable"
first. This was done by calling the function twice. Let the change_mode
function take care of this required step in a single call.

> diff --git a/drivers/net/ethernet/renesas/rswitch_main.c b/drivers/net/ethernet/renesas/rswitch_main.c
> index 6fe964816322..f6d1e610e7fa 100644
> --- a/drivers/net/ethernet/renesas/rswitch_main.c
> +++ b/drivers/net/ethernet/renesas/rswitch_main.c
> @@ -176,14 +176,19 @@ static int rswitch_gwca_change_mode(struct rswitch_private *priv,
>  	if (!rswitch_agent_clock_is_enabled(priv->addr, priv->gwca.index))
>  		rswitch_agent_clock_ctrl(priv->addr, priv->gwca.index, 1);
>
> -	iowrite32(mode, priv->addr + GWMC);
> +	iowrite32(GWMC_OPC_DISABLE, priv->addr + GWMC);
>
> -	ret = rswitch_reg_wait(priv->addr, GWMS, GWMS_OPS_MASK, mode);
> +	ret = rswitch_reg_wait(priv->addr, GWMS, GWMS_OPS_MASK, GWMC_OPC_DISABLE);
>
> -	if (mode == GWMC_OPC_DISABLE)
> +	if (mode == GWMC_OPC_DISABLE) {
>  		rswitch_agent_clock_ctrl(priv->addr, priv->gwca.index, 0);
>
> -	return ret;
> +		return ret;
> +	}
> +
> +	iowrite32(mode, priv->addr + GWMC);
> +
> +	return rswitch_reg_wait(priv->addr, GWMS, GWMS_OPS_MASK, mode);

Should the error from the initial DISABLE transition be checked before
proceeding? When mode != GWMC_OPC_DISABLE, this code stores the result of
rswitch_reg_wait() for the DISABLE transition in 'ret' but never checks it.
If the hardware fails to reach DISABLE state, the function silently proceeds
to write the target mode.

Before this patch, callers explicitly checked the error after calling
rswitch_gwca_change_mode(priv, GWMC_OPC_DISABLE):

rswitch_gwca_hw_init() and rswitch_gwca_hw_deinit():
    err = rswitch_gwca_change_mode(priv, GWMC_OPC_DISABLE);
    if (err < 0)
        return err;

This patch removes those caller-side checks but doesn't replicate the error
checking inside rswitch_gwca_change_mode(). If the first rswitch_reg_wait()
returns -ETIMEDOUT, should the function return that error before attempting
to write the target mode?

>  }
>
>  static int rswitch_gwca_mcast_table_reset(struct rswitch_private *priv)
> @@ -682,9 +687,6 @@ static int rswitch_gwca_hw_init(struct rswitch_private *priv)
>  	unsigned int i;
>  	int err;
>
> -	err = rswitch_gwca_change_mode(priv, GWMC_OPC_DISABLE);
> -	if (err < 0)
> -		return err;
>  	err = rswitch_gwca_change_mode(priv, GWMC_OPC_CONFIG);
>  	if (err < 0)
>  		return err;

[ ... ]

> @@ -717,9 +719,6 @@ static int rswitch_gwca_hw_init(struct rswitch_private *priv)
>  			return err;
>  	}
>
> -	err = rswitch_gwca_change_mode(priv, GWMC_OPC_DISABLE);
> -	if (err < 0)
> -		return err;
>  	return rswitch_gwca_change_mode(priv, GWMC_OPC_OPERATION);
>  }
>
> @@ -727,9 +726,6 @@ static int rswitch_gwca_hw_deinit(struct rswitch_private *priv)
>  {
>  	int err;
>
> -	err = rswitch_gwca_change_mode(priv, GWMC_OPC_DISABLE);
> -	if (err < 0)
> -		return err;
>  	err = rswitch_gwca_change_mode(priv, GWMC_OPC_RESET);
>  	if (err < 0)
>  		return err;

[ ... ]

> @@ -1116,14 +1112,18 @@ static int rswitch_etha_change_mode(struct rswitch_etha *etha,
>  	if (!rswitch_agent_clock_is_enabled(etha->coma_addr, etha->index))
>  		rswitch_agent_clock_ctrl(etha->coma_addr, etha->index, 1);
>
> -	iowrite32(mode, etha->addr + EAMC);
> -
> -	ret = rswitch_reg_wait(etha->addr, EAMS, EAMS_OPS_MASK, mode);
> +	iowrite32(EAMC_OPC_DISABLE, etha->addr + EAMC);
> +	ret = rswitch_reg_wait(etha->addr, EAMS, EAMS_OPS_MASK, EAMC_OPC_DISABLE);
>
> -	if (mode == EAMC_OPC_DISABLE)
> +	if (mode == EAMC_OPC_DISABLE) {
>  		rswitch_agent_clock_ctrl(etha->coma_addr, etha->index, 0);
>
> -	return ret;
> +		return ret;
> +	}
> +
> +	iowrite32(mode, etha->addr + EAMC);
> +
> +	return rswitch_reg_wait(etha->addr, EAMS, EAMS_OPS_MASK, mode);

Same pattern here in rswitch_etha_change_mode(). When mode !=
EAMC_OPC_DISABLE, the return value from rswitch_reg_wait() for the
intermediate DISABLE transition is stored in 'ret' but never checked.

Before this patch, rswitch_etha_hw_init() explicitly called
rswitch_etha_change_mode(etha, EAMC_OPC_DISABLE) with error checking before
calling it with EAMC_OPC_CONFIG. This patch removes that caller-side check
but doesn't replicate it inside the function. Should there be a check like
'if (ret < 0) return ret;' after the first rswitch_reg_wait()?

>  }
>
>  static void rswitch_etha_read_mac_address(struct rswitch_etha *etha)

[ ... ]


^ permalink raw reply

* [PATCH net] net: airoha: Fix memory leak in airoha_qdma_rx_process()
From: Lorenzo Bianconi @ 2026-04-02 12:57 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni
  Cc: linux-arm-kernel, linux-mediatek, netdev, Lorenzo Bianconi

If an error occurs on the subsequents buffers belonging to the
non-linear part of the skb (e.g. due to an error in the payload length
reported by the NIC or if we consumed all the available fragments for
the skb), the page_pool fragment will not be linked to the skb so it will
not return to the pool in the airoha_qdma_rx_process() error path. Fix the
memory leak partially reverting commit 'd6d2b0e1538d ("net: airoha: Fix
page recycling in airoha_qdma_rx_process()")' and always running
page_pool_put_full_page routine in the airoha_qdma_rx_process() error
path.

Fixes: d6d2b0e1538d ("net: airoha: Fix page recycling in airoha_qdma_rx_process()")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/ethernet/airoha/airoha_eth.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 95ba99b89428e4cafb91ff7813e43ffeb38e6d9b..91cb63a32d9904e0700bcce45b53624677d75c6c 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -697,9 +697,8 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
 		if (q->skb) {
 			dev_kfree_skb(q->skb);
 			q->skb = NULL;
-		} else {
-			page_pool_put_full_page(q->page_pool, page, true);
 		}
+		page_pool_put_full_page(q->page_pool, page, true);
 	}
 	airoha_qdma_fill_rx_queue(q);
 

---
base-commit: a1822cb524e89b4cd2cf0b82e484a2335496a6d9
change-id: 20260402-airoha_qdma_rx_process-mem-leak-fix-27b53dbaaa4f

Best regards,
-- 
Lorenzo Bianconi <lorenzo@kernel.org>


^ permalink raw reply related

* Re: [PATCH net-next v3 6/7] net: team: Decouple rx and tx enablement in the team driver
From: Jiri Pirko @ 2026-04-02 12:54 UTC (permalink / raw)
  To: Marc Harvey
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Shuah Khan, Simon Horman, netdev, linux-kernel,
	linux-kselftest
In-Reply-To: <20260402-teaming-driver-internal-v3-6-e8cfdec3b5c2@google.com>

Thu, Apr 02, 2026 at 08:24:19AM +0200, marcharvey@google.com wrote:
>There are use cases where an aggregated port should send traffic, but
>not receive traffic, and vice versa. For example, in the IEEE
>802.3ad-2000 specification, there is an optional "Independent Control"
>version of the mux machine. Currently there is no way create
>implementations like this for the team driver.
>
>Separate the existing "enabled" per-port option into tx and rx
>specific enablement options, but do so without breaking the existing
>"enabled" option. The existing "enabled" option is now defined as
>(rx_enabled AND tx_enabled), so if one is independently disabled, then
>the old "enabled" option will also not be enabled. However, setting
>the old "enabled" option affects both the rx_enabled and tx_enabled
>options. This is the first case where setting an option can affect
>another option.
>
>Note that teamd and any other software that exclusively uses "coupled"
>enablement will continue to work without any changes.
>
>Signed-off-by: Marc Harvey <marcharvey@google.com>
>---
>Changes in v3:
>- None
>
>Changes in v2:
>- None
>---
> drivers/net/team/team_core.c             | 238 ++++++++++++++++++++++++++-----
> drivers/net/team/team_mode_loadbalance.c |   4 +-
> drivers/net/team/team_mode_random.c      |   4 +-
> drivers/net/team/team_mode_roundrobin.c  |   2 +-
> include/linux/if_team.h                  |  60 +++++---
> 5 files changed, 245 insertions(+), 63 deletions(-)

I see multiple patches squashed here. Could you please split for
easier review?

Renames separate, preparations separate, adding rx_en separate, adding
tx_en separata etc?

Thanks!

^ permalink raw reply

* Re: [PATCH v3 0/4] gcov: use -fprofile-update=atomic globally to fix concurrent access crashes on GCOV-enabled kernels
From: Konstantin Khorenko @ 2026-04-02 12:48 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Peter Oberparleiter, Mikhail Zaslonko, Thomas Weißschuh,
	Steffen Klassert, Herbert Xu, Masahiro Yamada, Josh Poimboeuf,
	Vasileios Almpanis, Pavel Tikhomirov, linux-kernel, netdev,
	David S . Miller, Eric Dumazet, Paolo Abeni, Simon Horman,
	Arnd Bergmann
In-Reply-To: <20260401184625.2641899d@kernel.org>

On 4/2/26 03:46, Jakub Kicinski wrote:
> On Wed,  1 Apr 2026 17:20:16 +0300 Konstantin Khorenko wrote:
>> 1. Build fix for CONFIG_GCOV_PROFILE_ALL=y - skb_ext_total_length()
>>     BUILD_BUG_ON failure:
>>     https://lore.kernel.org/lkml/20260331165125.959833-1-khorenko@virtuozzo.com/T/#t
>>
>> 2. Runtime crash fix for zlib inflate_fast() - GCOV counter merging
>>     with loop induction variables caused out-of-bounds writes on SMP:
>>     https://lore.kernel.org/lkml/20260330143256.306326-1-khorenko@virtuozzo.com/T/#t
> 
> Why are you merging these? The should go via different subsystems.
> How do you expect this series to be applied?

You are definitely right, Jakub.

i will create 3 different threads and note explicitly that the last commit should be applied only 
after first 2 series are merged.

Will do right now!

--
Konstantin Khorenko

^ permalink raw reply

* [BUG] Linux Kernel ksmbd Multiple Memory Leaks in Session Handling
From: ven0mfuzzer @ 2026-04-02 11:07 UTC (permalink / raw)
  To: Namjae Jeon, Tom Talpey, Jakub Kicinski, Sergey Senozhatsky,
	Eric Dumazet, Kuniyuki Iwashima, David S. Miller, Paolo Abeni,
	Steve French, Neal Cardwell, Simon Horman, Willem de Bruijn,
	David Ahern
  Cc: linux-cifs, linux-kernel, netdev

Linux Kernel ksmbd Multiple Memory Leaks in Session Handling

  1. Vulnerability Title

Linux Kernel ksmbd Server Multiple Kernel Memory Leak Vulnerability in Session Setup/Teardown

  2. High-Level Overview

Seven distinct kernel memory leaks exist in the ksmbd (in-kernel SMB server) session handling paths. During SMB session setup and teardown, multiple kernel objects — including socket inodes (1344 bytes), LSM security blobs (120 and 32 bytes), TCP connection structures (3264 bytes), ksmbd connection contexts (64 and 16 bytes), and network skb buffers (240 bytes) — are allocated but never freed. These leaks accumulate over time with repeated session establishment, allowing a remote attacker to exhaust kernel memory by repeatedly connecting and disconnecting SMB sessions. This constitutes a denial-of-service vulnerability.

This vulnerability was discovered using ven0mfuzzer, our custom-designed MITM-based network filesystem fuzzer developed by our team. Following the common syzkaller practice, we submit the kernel crash trace as the primary reproduction artifact.

  3. Affected Product and Version Information

Product: Linux Kernel (upstream mainline)
Affected Component: `fs/smb/server/` — ksmbd session setup/teardown, connection handling
Supporting Components:
- `fs/smb/server/transport_tcp.c` — `ksmbd_kthread_fn()`, `ksmbd_tcp_readv()`
- `fs/smb/server/connection.c` — connection context allocation
- `net/socket.c` — `sock_alloc_inode()`, `kernel_accept()`
- `net/ipv4/tcp_minisocks.c` — `tcp_create_openreq_child()`

  Tested Versions (confirmed vulnerable)
- Linux kernel 6.19.0 (mainline, commit `44331bd6a610`, gcc 11.4.0, built 2026-02-13)
- Linux kernel 6.12.74 (LTS, used in Google kernelCTF COS target)

  Affected Version Range
All kernels with ksmbd support (approximately 5.15 through 6.19) are believed affected.

  Affected Distributions and Products

 |  Vendor / Product  |  Notes  | 
 | --- | --- | 
 |  Red Hat Enterprise Linux (RHEL 9.x)  |  Ships kernels >= 5.14 with ksmbd module  | 
 |  Ubuntu (22.04 LTS, 24.04 LTS)  |  HWE kernels 6.x include ksmbd  | 
 |  SUSE Linux Enterprise Server (SLES 15 SP5+)  |  Kernel 6.x based  | 
 |  Debian (Bookworm, Trixie)  |  Kernels 6.1+  | 
 |  Fedora (39+)  |  Kernels 6.5+  | 
 |  Amazon Linux 2023  |  Kernel 6.1 LTS based  | 
 |  Google ChromeOS / COS  |  kernelCTF target, confirmed vulnerable on 6.12.74  | 

  4. Root Cause Analysis

  4.a. Detailed Description

The kmemleak detector identified 7 unreferenced kernel objects allocated during ksmbd session handling that are never freed. These leaks occur across multiple subsystems involved in SMB connection management:

1. Socket inode (1344 bytes): Allocated by `sock_alloc_inode()` during `kernel_accept()` in `ksmbd_kthread_fn()`. The accepted socket's inode is not properly released when the connection is torn down.

2. LSM security blob (120 bytes): Allocated by `security_inode_alloc()` during inode initialization for the socket. Leaked because the parent inode is leaked.

3. TCP connection structure (3264 bytes): Allocated by `sk_prot_alloc()` during `tcp_create_openreq_child()` when accepting a new TCP connection. The TCP socket is not properly closed on session teardown.

4. LSM security blob for socket (32 bytes): Allocated by `security_sk_alloc()` for the cloned TCP socket. Leaked with the parent TCP structure.

5. ksmbd connection context (64 bytes): Allocated by `ksmbd_kthread_fn()` for per-connection state. Not freed when the connection handler exits abnormally.

6. ksmbd TCP read buffer (16 bytes): Allocated by `ksmbd_tcp_readv()` for receiving SMB messages. Not freed when read is interrupted.

7. SKB buffer (240 bytes): Allocated by `build_skb()` in the virtio-net receive path for incoming SMB packets. Orphaned when the associated socket is leaked.

  4.b. Code Flow

---
ksmbd_kthread_fn()                    [fs/smb/server/transport_tcp.c]
  → kernel_accept()                   ← allocates socket inode (1344B) + security blob (120B)
    → sock_alloc() → alloc_inode()
    → security_inode_alloc()

TCP SYN_RECV → ESTABLISHED:
  → tcp_create_openreq_child()        ← allocates TCP sock (3264B) + security blob (32B)
    → sk_prot_alloc() → sk_clone()
    → security_sk_alloc()

ksmbd_kthread_fn() continued:
  → kmalloc (64B)                     ← ksmbd connection context

ksmbd_conn_handler_loop():
  → ksmbd_tcp_readv()
    → kmalloc (16B)                   ← TCP read buffer

[on session teardown — objects NOT freed due to missing cleanup]
---

  4.c. Crash Trace

This vulnerability was discovered by ven0mfuzzer. The following kmemleak output is submitted following syzkaller's common practice of providing the raw kernel trace as the primary reproduction evidence:

---
unreferenced object 0xffff88810af3d180 (size 1344):
  comm "ksmbd-eth0", pid 328, jiffies 4294901355
  backtrace (crc 1a26ccb4):
    kmem_cache_alloc_lru_noprof+0x3ed/0x5f0
    sock_alloc_inode+0x25/0x1c0
    alloc_inode+0x64/0x240
    sock_alloc+0x40/0x280
    sock_create_lite+0x82/0x120
    kernel_accept+0x16b/0x380
    ksmbd_kthread_fn+0xee/0xf30

unreferenced object 0xffff888107243bd0 (size 120):
  comm "ksmbd-eth0", pid 328, jiffies 4294901355
  backtrace (crc 6bd3e180):
    kmem_cache_alloc_noprof+0x3ed/0x5f0
    security_inode_alloc+0x3b/0x140
    inode_init_always_gfp+0xbf9/0xf20
    alloc_inode+0x86/0x240
    sock_alloc+0x40/0x280
    sock_create_lite+0x82/0x120
    kernel_accept+0x16b/0x380
    ksmbd_kthread_fn+0xee/0xf30

unreferenced object 0xffff88810fbfa980 (size 3264):
  comm "softirq", pid 0, jiffies 4294902189
  backtrace (crc c2de1a0c):
    kmem_cache_alloc_noprof+0x3ed/0x5f0
    sk_prot_alloc+0x60/0x2a0
    sk_clone+0x79/0x14f0
    inet_csk_clone_lock+0x2f/0x760
    tcp_create_openreq_child+0x34/0x26a0
    tcp_v4_syn_recv_sock+0x115/0x10e0

unreferenced object 0xffff888108c514a0 (size 32):
  comm "softirq", pid 0, jiffies 4294902189
  backtrace (crc ea16adaf):
    __kmalloc_noprof+0x4eb/0x760
    lsm_blob_alloc+0x68/0x90
    security_sk_alloc+0x2f/0xd0
    sk_prot_alloc+0xfb/0x2a0
    sk_clone+0x79/0x14f0

unreferenced object 0xffff88810fd0b540 (size 64):
  comm "ksmbd-eth0", pid 328, jiffies 4294902189
  backtrace (crc f2da5eae):
    __kmalloc_cache_noprof+0x411/0x610
    ksmbd_kthread_fn+0x288/0xf30

unreferenced object 0xffff8881063426f0 (size 16):
  comm "ksmbd:::ffff:10", pid 434, jiffies 4294902190
  backtrace (crc 9e6ee6c8):
    __kmalloc_cache_noprof+0x411/0x610
    ksmbd_tcp_readv.constprop.0+0x16d/0x700
    ksmbd_tcp_read+0x88/0xc0
    ksmbd_conn_handler_loop+0x5dd/0xfd0

unreferenced object 0xffff88810fa94200 (size 240):
  comm "softirq", pid 0, jiffies 4294902419
  backtrace (crc 4367e44b):
    kmem_cache_alloc_noprof+0x3ed/0x5f0
    build_skb+0x46/0x370
    page_to_skb+0x5df/0xb30
    receive_buf+0xa3e/0x4940
    virtnet_poll+0xfb6/0x1750
---

Total leaked per session: approximately 5,080 bytes (1344 + 120 + 3264 + 32 + 64 + 16 + 240). An attacker establishing and tearing down sessions repeatedly can exhaust kernel memory.

  4.d. Suggested Fix

The ksmbd session teardown path (`ksmbd_sessions_deregister` / `ksmbd_conn_handler_loop` exit) must properly release all allocated resources:
1. Close the accepted socket via `sock_release()` to free the socket inode and associated LSM blobs
2. Properly tear down the cloned TCP socket
3. Free the ksmbd connection context and read buffers on all exit paths, including error/abort paths

  5. Discovery Method and Reproduction

  5.a. Discovery

This vulnerability was discovered using ven0mfuzzer, a custom-designed MITM-based network filesystem fuzzer developed by our team. The fuzzer operates by positioning an AF_PACKET/TCP transparent proxy between a Linux kernel filesystem client (VM-A) and its server (VM-B), then mutating network protocol messages in-flight.

Following the common syzkaller practice, we submit the kernel kmemleak output as the primary reproduction artifact. The output above was captured with CONFIG_DEBUG_KMEMLEAK enabled on kernel 6.19.0.

  5.b. Reproduction Setup

---
VM-A (CIFS client) ──SMB2──► Host:44446 (MITM proxy) ──TCP──► Host:44445 ──hostfwd──► VM-B:445 (ksmbd)
---

Trigger condition: Repeated SMB session establishment and teardown, especially when the MITM proxy disrupts the session setup handshake, forcing abnormal teardown paths.

---
Reported-by: ven0mfuzzer <ven0mkernelfuzzer@gmail.com>
Link: https://github.com/KernelStackFuzz/KernelStackFuzz

^ permalink raw reply

* [PATCH v1 09/22] dt-bindings: clock: Add StarFive JHB100 System-2 clock and reset generator
From: Changhuang Liang @ 2026-04-02 10:55 UTC (permalink / raw)
  To: Michael Turquette, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Stephen Boyd, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Philipp Zabel, Emil Renner Berthing, Kees Cook,
	Gustavo A . R . Silva, Richard Cochran
  Cc: linux-clk, linux-kernel, devicetree, linux-riscv, linux-hardening,
	netdev, Sia Jee Heng, Hal Feng, Ley Foon Tan, Changhuang Liang
In-Reply-To: <20260402105523.447523-1-changhuang.liang@starfivetech.com>

Add bindings for the System-2 clocks and reset generator (SYS2CRG) on
JHB100 SoC.

Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
---
 .../clock/starfive,jhb100-sys2crg.yaml        | 64 +++++++++++++++++++
 .../dt-bindings/clock/starfive,jhb100-crg.h   | 33 ++++++++++
 .../dt-bindings/reset/starfive,jhb100-crg.h   | 26 ++++++++
 3 files changed, 123 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/starfive,jhb100-sys2crg.yaml

diff --git a/Documentation/devicetree/bindings/clock/starfive,jhb100-sys2crg.yaml b/Documentation/devicetree/bindings/clock/starfive,jhb100-sys2crg.yaml
new file mode 100644
index 000000000000..5f71e761be23
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/starfive,jhb100-sys2crg.yaml
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/starfive,jhb100-sys2crg.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JHB100 System-2 Clock and Reset Generator
+
+maintainers:
+  - Changhuang Liang <changhuang.liang@starfivetech.com>
+
+properties:
+  compatible:
+    const: starfive,jhb100-sys2crg
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Main Oscillator (25 MHz)
+      - description: PLL1
+      - description: System-2 GPU0 600MHz
+      - description: System-2 GPU1 600MHz
+
+  clock-names:
+    items:
+      - const: osc
+      - const: pll1
+      - const: sys2_gpu0_600
+      - const: sys2_gpu1_600
+
+  '#clock-cells':
+    const: 1
+    description:
+      See <dt-bindings/clock/starfive,jhb100-crg.h> for valid indices.
+
+  '#reset-cells':
+    const: 1
+    description:
+      See <dt-bindings/reset/starfive-jhb100-crg.h> for valid indices.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - '#clock-cells'
+  - '#reset-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller@13008000 {
+      compatible = "starfive,jhb100-sys2crg";
+      reg = <0x13008000 0x4000>;
+      clocks = <&osc>, <&pll1>, <&sys0crg 73>,
+               <&sys0crg 74>;
+      clock-names = "osc", "pll1", "sys2_gpu0_600",
+              "sys2_gpu1_600";
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+    };
diff --git a/include/dt-bindings/clock/starfive,jhb100-crg.h b/include/dt-bindings/clock/starfive,jhb100-crg.h
index 510a5c6fa89a..34e4498fc1c8 100644
--- a/include/dt-bindings/clock/starfive,jhb100-crg.h
+++ b/include/dt-bindings/clock/starfive,jhb100-crg.h
@@ -73,4 +73,37 @@
 #define JHB100_SYS1CLK_BMCPER3_100			18
 #define JHB100_SYS1CLK_BMCPER3_125			19
 
+/* SYS2CRG clocks */
+#define JHB100_SYS2CLK_JTAGM0_200			3
+#define JHB100_SYS2CLK_JTAGM1_200			4
+#define JHB100_SYS2CLK_JTAGM0_100			5
+#define JHB100_SYS2CLK_JTAGM1_100			6
+#define JHB100_SYS2CLK_JTAGM0_ATPG_TCLOCK		7
+#define JHB100_SYS2CLK_JTAGM1_ATPG_TCLOCK		8
+#define JHB100_SYS2CLK_JTAG0_MST_WRAP_HCLK		9
+#define JHB100_SYS2CLK_JTAG0_MST_WRAP_CLK_JTAG		10
+#define JHB100_SYS2CLK_JTAG0_MST_WRAP_APB_PCLK		11
+#define JHB100_SYS2CLK_JTAG0_MST_WRAP_ATPG_TCLOCK	12
+#define JHB100_SYS2CLK_JTAG1_MST_WRAP_HCLK		13
+#define JHB100_SYS2CLK_JTAG1_MST_WRAP_CLK_JTAG		14
+#define JHB100_SYS2CLK_JTAG1_MST_WRAP_APB_PCLK		15
+#define JHB100_SYS2CLK_JTAG1_MST_WRAP_ATPG_TCLOCK	16
+#define JHB100_SYS2CLK_HOSTUSB_100			17
+#define JHB100_SYS2CLK_HOSTUSBCMN_500			18
+#define JHB100_SYS2CLK_BMCPER1_200			19
+#define JHB100_SYS2CLK_BMCPER1_250			20
+#define JHB100_SYS2CLK_BMCPER1_143_DFT			21
+#define JHB100_SYS2CLK_BMCPER1_143			22
+#define JHB100_SYS2CLK_BMCPER0_200			23
+#define JHB100_SYS2CLK_GPU0_100				24
+#define JHB100_SYS2CLK_GPU0_BUS_CLK			25
+#define JHB100_SYS2CLK_GPU0_APB_CLK			26
+#define JHB100_SYS2CLK_GPU0_OSC_CLK			27
+#define JHB100_SYS2CLK_GPU1_100				28
+#define JHB100_SYS2CLK_GPU1_BUS_CLK			29
+#define JHB100_SYS2CLK_GPU1_APB_CLK			30
+#define JHB100_SYS2CLK_GPU1_OSC_CLK			31
+#define JHB100_SYS2CLK_MAIN_ICG_EN_JTAG0		32
+#define JHB100_SYS2CLK_MAIN_ICG_EN_JTAG1		33
+
 #endif /* __DT_BINDINGS_CLOCK_STARFIVE_JHB100_H__ */
diff --git a/include/dt-bindings/reset/starfive,jhb100-crg.h b/include/dt-bindings/reset/starfive,jhb100-crg.h
index 9a0ab64abafa..d92bc4c6d830 100644
--- a/include/dt-bindings/reset/starfive,jhb100-crg.h
+++ b/include/dt-bindings/reset/starfive,jhb100-crg.h
@@ -40,4 +40,30 @@
 #define JHB100_SYS1RST_BMCPERIPH3_RSTN_CRG				13
 #define JHB100_SYS1RST_BMCPERIPH3_RSTN_BUS				14
 
+/* SYS2CRG resets */
+#define JHB100_SYS2RST_JTAG0_MST_WRAP_HRESETN				2
+#define JHB100_SYS2RST_JTAG0_MST_WRAP_APB_PRESETN			3
+#define JHB100_SYS2RST_JTAG1_MST_WRAP_HRESETN				4
+#define JHB100_SYS2RST_JTAG1_MST_WRAP_APB_PRESETN			5
+
+#define JHB100_SYS2RST_HUSBCMN_HOSTCMN_RSTN_BUS_NCNOC_INIT		8
+#define JHB100_SYS2RST_HUSBCMN_RSTN_HOSTCMN_CRG				9
+#define JHB100_SYS2RST_HUSBCMN_HOSTUSB0_RSTN_BUS_NCNOC_BMC_TARG		10
+#define JHB100_SYS2RST_HUSBCMN_HOSTUSB0_RSTN_BUS_NCNOC_HOST_TARG	11
+#define JHB100_SYS2RST_HUSBCMN_RSTN_BMC_CRG				12
+#define JHB100_SYS2RST_HUSBCMN_RSTN_HOSTUSB0_CRG			13
+#define JHB100_SYS2RST_HUSBCMN_HOSTUSB1_RSTN_BUS_NCNOC_BMC_TARG		14
+#define JHB100_SYS2RST_HUSBCMN_HOSTUSB1_RSTN_BUS_NCNOC_HOST_TARG	15
+#define JHB100_SYS2RST_HUSBCMN_RSTN_HOSTUSB1_CRG			16
+#define JHB100_SYS2RST_BMCPERIPH1_RSTN_CRG				17
+#define JHB100_SYS2RST_BMCPERIPH1_RSTN_BUS				18
+#define JHB100_SYS2RST_BMCPERIPH0_RSTN_CRG				19
+#define JHB100_SYS2RST_BMCPERIPH0_RSTN_BUS				20
+#define JHB100_SYS2RST_GPU0_RSTN_CRG					21
+#define JHB100_SYS2RST_GPU0_RSTN_BUS					22
+#define JHB100_SYS2RST_GPU0_HOST_PCIE_RST_N				23
+#define JHB100_SYS2RST_GPU1_RSTN_CRG					24
+#define JHB100_SYS2RST_GPU1_RSTN_BUS					25
+#define JHB100_SYS2RST_GPU1_HOST_PCIE_RST_N				26
+
 #endif /* __DT_BINDINGS_RESET_STARFIVE_JHB100_CRG_H__ */
-- 
2.25.1


^ permalink raw reply related

* Re: RFC: phylink: disable PHY autonomous EEE when MAC manages LPI
From: Russell King (Oracle) @ 2026-04-02 12:32 UTC (permalink / raw)
  To: Nicolai Buchwitz; +Cc: Andrew Lunn, netdev
In-Reply-To: <4950b35ad3df1e8a09d063907dad32a3@tipi-net.de>

On Thu, Apr 02, 2026 at 09:53:37AM +0200, Nicolai Buchwitz wrote:
> On 1.4.2026 18:02, Russell King (Oracle) wrote:
> > On Wed, Apr 01, 2026 at 05:38:23PM +0200, Andrew Lunn wrote:
> > > On Wed, Apr 01, 2026 at 04:05:32PM +0100, Russell King (Oracle) wrote:
> > > > On Wed, Apr 01, 2026 at 03:11:24PM +0200, Andrew Lunn wrote:
> > > > > > Thanks Russell and Andrew. You're both heading in the same direction,
> > > > > > so to make sure I understand correctly:
> > > > > >
> > > > > > 1. Add a new phylib interface (separate from phy_ethtool_set_eee) to
> > > > > >    control PHY-autonomous EEE, e.g. phy_set_autonomous_eee(phydev,
> > > > > >    enable) and phy_get_autonomous_eee(phydev) to query the current
> > > > > >    state.
> > > > >
> > > > > In the end, we want the MAC driver using phylib to just call the
> > > > > phylib methods for configuring EEE, and the MAC driver should not care
> > > > > if EEE is actually implemented in the PHY or the MAC. The adjust_link
> > > > > callback would simply not enable LPI if the PHY is doing EEE.
> > > >
> > > > This won't work.
> > > >
> > > > If we mask out eee.tx_lpi_enabled when calling into phylib to tell
> > > > phylib drivers to disable SmartEEE (that's what I'm calling it here
> > > > because it's easier to type)),
> > > 
> > > We need phylib to handle some state information. Are we doing MAC EEE
> > > or SmartEEE? We can then set phydev->enable_tx_lpi == True to indicate
> > > if the MAC should be sending LPI indications, if and only if the
> > > phylib knows we are doing MAC EEE and it should be enabled because the
> > > user said so.
> > 
> > Right, and that's why I suggested phy_disable_autonomous_eee() to tell
> > phylib to disable SmartEEE/autonomous EEE support at the PHY independent
> > of phy_ethtool_set_eee().
> > 
> > I was also suggesting that there's eventually a complementary function
> > that says basically "please enable SmartEEE" because we may have phy
> > drivers that disable it today.
> > 
> > In absence of either call, phy drivers need to maintain their current
> > state.
> > 
> > > However, i think this is down the road. If the MAC driver calls
> > > phy_support_eee(), we should call the SmartEEE disable method of the
> > > PHY driver. When we add support for SmartEEE then we need this
> > > additional state information.
> > 
> > That also works for me.
> 
> Thanks both. So if I understand correctly:
> 
> 1. Add a .disable_autonomous_eee callback to struct phy_driver
> 
> 2. Call it from phy_support_eee() so MAC drivers don't need to know
>    or care whether the PHY does (autonomous|smart)eee
> 
> 3. BCM54xx (AutogrEEEn) and RTL8211F as first users
> 
> 4. No enable counterpart for now. PHY drivers maintain their current
>    default behavior unless phy_support_eee() is called.
> 
> Sounds good. Sorting out the warts of (autonomous|smart)eee will be
> iterative anyway, so starting with just the disable path makes sense
> (and hopefully will make setups a bit less broken than they were with
> both fighting for LPI).
> 
> I'll put the RFC patches together.

Sounds good to me, but I'd wait for Andrew's input.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply

* [PATCH v1 14/22] clk: starfive: Add StarFive JHB100 Peripheral-0 clock driver
From: Changhuang Liang @ 2026-04-02 10:55 UTC (permalink / raw)
  To: Michael Turquette, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Stephen Boyd, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Philipp Zabel, Emil Renner Berthing, Kees Cook,
	Gustavo A . R . Silva, Richard Cochran
  Cc: linux-clk, linux-kernel, devicetree, linux-riscv, linux-hardening,
	netdev, Sia Jee Heng, Hal Feng, Ley Foon Tan, Changhuang Liang
In-Reply-To: <20260402105523.447523-1-changhuang.liang@starfivetech.com>

Add driver for the StarFive JHB100 Peripheral-0 clock controller.

Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
---
 drivers/clk/starfive/Kconfig                  |   8 +
 drivers/clk/starfive/Makefile                 |   1 +
 .../clk/starfive/clk-starfive-jhb100-per0.c   | 655 ++++++++++++++++++
 3 files changed, 664 insertions(+)
 create mode 100644 drivers/clk/starfive/clk-starfive-jhb100-per0.c

diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
index 729bdfce7b8a..adf97444f460 100644
--- a/drivers/clk/starfive/Kconfig
+++ b/drivers/clk/starfive/Kconfig
@@ -73,6 +73,14 @@ config CLK_STARFIVE_JH7110_VOUT
 	  Say yes here to support the Video-Output clock controller
 	  on the StarFive JH7110 SoC.
 
+config CLK_STARFIVE_JHB100_PER0
+	bool "StarFive JHB100 peripheral-0 clock support"
+	depends on CLK_STARFIVE_JHB100_SYS2
+	default ARCH_STARFIVE
+	help
+	  Say yes here to support the peripheral-0 clock controller
+	  on the StarFive JHB100 SoC.
+
 config CLK_STARFIVE_JHB100_SYS0
 	bool "StarFive JHB100 system-0 clock support"
 	depends on ARCH_STARFIVE || COMPILE_TEST
diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
index 90b6390296bd..2f605d0fd6da 100644
--- a/drivers/clk/starfive/Makefile
+++ b/drivers/clk/starfive/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_CLK_STARFIVE_JH7110_STG)	+= clk-starfive-jh7110-stg.o
 obj-$(CONFIG_CLK_STARFIVE_JH7110_ISP)	+= clk-starfive-jh7110-isp.o
 obj-$(CONFIG_CLK_STARFIVE_JH7110_VOUT)	+= clk-starfive-jh7110-vout.o
 
+obj-$(CONFIG_CLK_STARFIVE_JHB100_PER0)		+= clk-starfive-jhb100-per0.o
 obj-$(CONFIG_CLK_STARFIVE_JHB100_SYS0)		+= clk-starfive-jhb100-sys0.o
 obj-$(CONFIG_CLK_STARFIVE_JHB100_SYS1)		+= clk-starfive-jhb100-sys1.o
 obj-$(CONFIG_CLK_STARFIVE_JHB100_SYS2)		+= clk-starfive-jhb100-sys2.o
diff --git a/drivers/clk/starfive/clk-starfive-jhb100-per0.c b/drivers/clk/starfive/clk-starfive-jhb100-per0.c
new file mode 100644
index 000000000000..e8fbf3ba308d
--- /dev/null
+++ b/drivers/clk/starfive/clk-starfive-jhb100-per0.c
@@ -0,0 +1,655 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * StarFive JHB100 Peripheral-0 Clock Driver
+ *
+ * Copyright (C) 2024 StarFive Technology Co., Ltd.
+ *
+ * Author: Changhuang Liang <changhuang.liang@starfivetech.com>
+ *
+ */
+
+#include <dt-bindings/clock/starfive,jhb100-crg.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+#include "clk-starfive-jhb100.h"
+
+#define JHB100_PER0CLK_NUM_CLKS			(JHB100_PER0CLK_MAIN_ICG_EN_TRNG + 1)
+
+/* external clocks */
+#define JHB100_PER0CLK_200_INIT			(JHB100_PER0CLK_NUM_CLKS + 0)
+#define JHB100_PER0CLK_400			(JHB100_PER0CLK_NUM_CLKS + 1)
+#define JHB100_PER0CLK_600			(JHB100_PER0CLK_NUM_CLKS + 2)
+#define JHB100_PER0CLK_OSC			(JHB100_PER0CLK_NUM_CLKS + 3)
+#define JHB100_PER0CLK_800			(JHB100_PER0CLK_NUM_CLKS + 4)
+#define JHB100_PER0CLK_PLL6			(JHB100_PER0CLK_NUM_CLKS + 5)
+
+static const struct starfive_clk_data jhb100_per0crg_clk_data[] = {
+	STARFIVE_GATE(JHB100_PER0CLK_CDR_I3C0, "cdr_i3c0", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_800),
+	STARFIVE_GATE(JHB100_PER0CLK_CDR_I3C1, "cdr_i3c1", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_800),
+	STARFIVE_GATE(JHB100_PER0CLK_CDR_I3C2, "cdr_i3c2", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_800),
+	STARFIVE_GATE(JHB100_PER0CLK_CDR_I3C3, "cdr_i3c3", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_800),
+	STARFIVE_GATE(JHB100_PER0CLK_CDR_I3C4, "cdr_i3c4", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_800),
+	STARFIVE_GATE(JHB100_PER0CLK_CDR_I3C5, "cdr_i3c5", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_800),
+	STARFIVE_GATE(JHB100_PER0CLK_CDR_I3C6, "cdr_i3c6", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_800),
+	STARFIVE_GATE(JHB100_PER0CLK_CDR_I3C7, "cdr_i3c7", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_800),
+	STARFIVE_GATE(JHB100_PER0CLK_CDR_I3C8, "cdr_i3c8", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_800),
+	STARFIVE_GATE(JHB100_PER0CLK_CDR_I3C9, "cdr_i3c9", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_800),
+	STARFIVE_GATE(JHB100_PER0CLK_CDR_I3C10, "cdr_i3c10", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_800),
+	STARFIVE_GATE(JHB100_PER0CLK_CDR_I3C11, "cdr_i3c11", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_800),
+	STARFIVE_GATE(JHB100_PER0CLK_CDR_I3C12, "cdr_i3c12", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_800),
+	STARFIVE_GATE(JHB100_PER0CLK_CDR_I3C13, "cdr_i3c13", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_800),
+	STARFIVE_GATE(JHB100_PER0CLK_CDR_I3C14, "cdr_i3c14", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_800),
+	STARFIVE_GATE(JHB100_PER0CLK_CDR_I3C15, "cdr_i3c15", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_800),
+	STARFIVE__DIV(JHB100_PER0CLK_200, "per0_200", 3,
+		      JHB100_PER0CLK_600),
+	STARFIVE__DIV(JHB100_PER0CLK_600_DIV6, "per0_600_div6", 6,
+		      JHB100_PER0CLK_600),
+	STARFIVE__DIV(JHB100_PER0CLK_600_DIV6_DIV5, "per0_600_div6_div5", 5,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_TIMER0_DUALTIMER0, "timer0_dualtimer0", 0,
+		      JHB100_PER0CLK_600_DIV6_DIV5),
+	STARFIVE_GATE(JHB100_PER0CLK_TIMER1_DUALTIMER0, "timer1_dualtimer0", 0,
+		      JHB100_PER0CLK_600_DIV6_DIV5),
+	STARFIVE_GATE(JHB100_PER0CLK_TIMER0_DUALTIMER1, "timer0_dualtimer1", 0,
+		      JHB100_PER0CLK_600_DIV6_DIV5),
+	STARFIVE_GATE(JHB100_PER0CLK_TIMER1_DUALTIMER1, "timer1_dualtimer1", 0,
+		      JHB100_PER0CLK_600_DIV6_DIV5),
+	STARFIVE_GATE(JHB100_PER0CLK_TIMER0_DUALTIMER2, "timer0_dualtimer2", 0,
+		      JHB100_PER0CLK_600_DIV6_DIV5),
+	STARFIVE_GATE(JHB100_PER0CLK_TIMER1_DUALTIMER2, "timer1_dualtimer2", 0,
+		      JHB100_PER0CLK_600_DIV6_DIV5),
+	STARFIVE__DIV(JHB100_PER0CLK_1200_PH0_LVDS0, "1200_ph0_lvds0", 2,
+		      JHB100_PER0CLK_PH0_LTPI0),
+	STARFIVE__DIV(JHB100_PER0CLK_1200_PH0_LVDS1, "1200_ph0_lvds1", 2,
+		      JHB100_PER0CLK_PH0_LTPI1),
+	STARFIVE__DIV(JHB100_PER0CLK_1200_CORE0, "1200_core0", 2,
+		      JHB100_PER0CLK_PLL6),
+	STARFIVE__DIV(JHB100_PER0CLK_1200_CORE1, "1200_core1", 2,
+		      JHB100_PER0CLK_PLL6),
+	STARFIVE__DIV(JHB100_PER0CLK_1200_SHIFT90_LVDS0, "1200_shift90_lvds0", 2,
+		      JHB100_PER0CLK_PH90_LTPI0),
+	STARFIVE__DIV(JHB100_PER0CLK_1200_SHIFT90_LVDS1, "1200_shift90_lvds1", 2,
+		      JHB100_PER0CLK_PH90_LTPI1),
+	STARFIVE__DIV(JHB100_PER0CLK_1200_DIV5_CORE0, "1200_div5_core0", 5,
+		      JHB100_PER0CLK_1200_CORE0),
+	STARFIVE__DIV(JHB100_PER0CLK_1200_DIV5_CORE1, "1200_div5_core1", 5,
+		      JHB100_PER0CLK_1200_CORE1),
+	STARFIVE__DIV(JHB100_PER0CLK_PH0_LTPI0, "ph0_ltpi0", 48,
+		      JHB100_PER0CLK_PLL6),
+	STARFIVE__DIV(JHB100_PER0CLK_PH0_LTPI1, "ph0_ltpi1", 48,
+		      JHB100_PER0CLK_PLL6),
+	STARFIVE_IDIV(JHB100_PER0CLK_PH90_LTPI0, "ph90_ltpi0", 0, 48,
+		      JHB100_PER0CLK_PLL6),
+	STARFIVE_IDIV(JHB100_PER0CLK_PH90_LTPI1, "ph90_ltpi1", 0, 48,
+		      JHB100_PER0CLK_PLL6),
+	STARFIVE__DIV(JHB100_PER0CLK_240_CORE_LTPI0, "240_core_ltpi0", 4,
+		      JHB100_PER0CLK_1200_DIV5_CORE0),
+	STARFIVE__DIV(JHB100_PER0CLK_240_CORE_LTPI1, "240_core_ltpi1", 4,
+		      JHB100_PER0CLK_1200_DIV5_CORE1),
+	STARFIVE_GATE(JHB100_PER0CLK_AXI_DMA_I2C_INIT, "axi_dma_i2c_init", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_400),
+	STARFIVE_GATE(JHB100_PER0CLK_AXI_DMA_I3C_INIT, "axi_dma_i3c_init", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_400),
+	STARFIVE_GATE(JHB100_PER0CLK_AXI_DMA_UART_INIT, "axi_dma_uart_init", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_400),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_DMAC0, "core_dmac0", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_200_INIT),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_DMAC1, "core_dmac1", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_200_INIT),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_DMAC2, "core_dmac2", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_200_INIT),
+	STARFIVE_GATE(JHB100_PER0CLK_HDR_TX_I3C0, "hdr_tx_i3c0", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_HDR_TX_I3C1, "hdr_tx_i3c1", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_HDR_TX_I3C2, "hdr_tx_i3c2", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_HDR_TX_I3C3, "hdr_tx_i3c3", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_HDR_TX_I3C4, "hdr_tx_i3c4", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_HDR_TX_I3C5, "hdr_tx_i3c5", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_HDR_TX_I3C6, "hdr_tx_i3c6", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_HDR_TX_I3C7, "hdr_tx_i3c7", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_HDR_TX_I3C8, "hdr_tx_i3c8", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_HDR_TX_I3C9, "hdr_tx_i3c9", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_HDR_TX_I3C10, "hdr_tx_i3c10", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_HDR_TX_I3C11, "hdr_tx_i3c11", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_HDR_TX_I3C12, "hdr_tx_i3c12", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_HDR_TX_I3C13, "hdr_tx_i3c13", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_HDR_TX_I3C14, "hdr_tx_i3c14", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_HDR_TX_I3C15, "hdr_tx_i3c15", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I2C0, "core_i2c0", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I2C1, "core_i2c1", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I2C2, "core_i2c2", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I2C3, "core_i2c3", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I2C4, "core_i2c4", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I2C5, "core_i2c5", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I2C6, "core_i2c6", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I2C7, "core_i2c7", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I2C8, "core_i2c8", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I2C9, "core_i2c9", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I2C10, "core_i2c10", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I2C11, "core_i2c11", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I2C12, "core_i2c12", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I2C13, "core_i2c13", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I2C14, "core_i2c14", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I2C15, "core_i2c15", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_WDOGCLK_WDT0, "wdogclk_wdt0", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_WDOGCLK_WDT1, "wdogclk_wdt1", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_WDOGCLK_WDT2, "wdogclk_wdt2", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_WDOGCLK_WDT3, "wdogclk_wdt3", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_WDOGCLK_WDT_EXTERNAL, "wdogclk_wdt_external",
+		      CLK_IGNORE_UNUSED, JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_SCLK_UART4, "sclk_uart4", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_SCLK_UART5, "sclk_uart5", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_SCLK_UART6, "sclk_uart6", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_SCLK_UART7, "sclk_uart7", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_SCLK_UART8, "sclk_uart8", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_SCLK_UART9, "sclk_uart9", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_SCLK_UART10, "sclk_uart10", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_SCLK_UART11, "sclk_uart11", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_SCLK_UART12, "sclk_uart12", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_SCLK_UART13, "sclk_uart13", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_SCLK_UART14, "sclk_uart14", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_PCLK_DMA_UART_CFG, "pclk_dma_uart_cfg", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_PCLK_DMA_I2C_CFG, "pclk_dma_i2c_cfg", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_PCLK_DMA_I3C_CFG, "pclk_dma_i3c_cfg", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_PCLK_DUALTIMER0, "pclk_dualtimer0", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_PCLK_DUALTIMER1, "pclk_dualtimer1", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_PCLK_DUALTIMER2, "pclk_dualtimer2", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_HCLK_TRNG, "hclk_trng", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_200_INIT),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2C0, "apb_i2c0", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2C1, "apb_i2c1", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2C2, "apb_i2c2", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2C3, "apb_i2c3", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2C4, "apb_i2c4", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2C5, "apb_i2c5", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2C6, "apb_i2c6", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2C7, "apb_i2c7", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2C8, "apb_i2c8", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2C9, "apb_i2c9", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2C10, "apb_i2c10", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2C11, "apb_i2c11", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2C12, "apb_i2c12", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2C13, "apb_i2c13", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2C14, "apb_i2c14", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2C15, "apb_i2c15", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2CF0, "apb_i2cf0", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2CF1, "apb_i2cf1", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2CF2, "apb_i2cf2", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2CF3, "apb_i2cf3", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2CF4, "apb_i2cf4", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2CF5, "apb_i2cf5", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2CF6, "apb_i2cf6", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2CF7, "apb_i2cf7", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2CF8, "apb_i2cf8", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2CF9, "apb_i2cf9", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2CF10, "apb_i2cf10", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2CF11, "apb_i2cf11", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2CF12, "apb_i2cf12", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2CF13, "apb_i2cf13", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2CF14, "apb_i2cf14", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I2CF15, "apb_i2cf15", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I3C0, "apb_i3c0", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I3C1, "apb_i3c1", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I3C2, "apb_i3c2", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I3C3, "apb_i3c3", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I3C4, "apb_i3c4", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I3C5, "apb_i3c5", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I3C6, "apb_i3c6", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I3C7, "apb_i3c7", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I3C8, "apb_i3c8", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I3C9, "apb_i3c9", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I3C10, "apb_i3c10", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I3C11, "apb_i3c11", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I3C12, "apb_i3c12", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I3C13, "apb_i3c13", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I3C14, "apb_i3c14", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_I3C15, "apb_i3c15", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_UART0, "apb_uart0", CLK_IS_CRITICAL,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_UART1, "apb_uart1", CLK_IS_CRITICAL,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_UART2, "apb_uart2", CLK_IS_CRITICAL,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_UART3, "apb_uart3", CLK_IS_CRITICAL,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_UART4, "apb_uart4", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_UART5, "apb_uart5", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_UART6, "apb_uart6", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_UART7, "apb_uart7", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_UART8, "apb_uart8", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_UART9, "apb_uart9", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_UART10, "apb_uart10", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_UART11, "apb_uart11", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_UART12, "apb_uart12", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_UART13, "apb_uart13", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_APB_UART14, "apb_uart14", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_DMA_I3C0, "dma_i3c0", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_DMA_I3C1, "dma_i3c1", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_DMA_I3C2, "dma_i3c2", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_DMA_I3C3, "dma_i3c3", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_DMA_I3C4, "dma_i3c4", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_DMA_I3C5, "dma_i3c5", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_DMA_I3C6, "dma_i3c6", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_DMA_I3C7, "dma_i3c7", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_DMA_I3C8, "dma_i3c8", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_DMA_I3C9, "dma_i3c9", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_DMA_I3C10, "dma_i3c10", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_DMA_I3C11, "dma_i3c11", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_DMA_I3C12, "dma_i3c12", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_DMA_I3C13, "dma_i3c13", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_DMA_I3C14, "dma_i3c14", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_DMA_I3C15, "dma_i3c15", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I3C0, "core_i3c0", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I3C1, "core_i3c1", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I3C2, "core_i3c2", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I3C3, "core_i3c3", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I3C4, "core_i3c4", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I3C5, "core_i3c5", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I3C6, "core_i3c6", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I3C7, "core_i3c7", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I3C8, "core_i3c8", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I3C9, "core_i3c9", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I3C10, "core_i3c10", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I3C11, "core_i3c11", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I3C12, "core_i3c12", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I3C13, "core_i3c13", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I3C14, "core_i3c14", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_CORE_I3C15, "core_i3c15", CLK_IGNORE_UNUSED,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_DMAC_AXI_PERIPH0_HS_CLK_I2C, "dmac_axi_periph0_hs_clk_i2c",
+		      CLK_IGNORE_UNUSED, JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C0, "main_icg_en_i3c0", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C1, "main_icg_en_i3c1", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C2, "main_icg_en_i3c2", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C3, "main_icg_en_i3c3", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C4, "main_icg_en_i3c4", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C5, "main_icg_en_i3c5", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C6, "main_icg_en_i3c6", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C7, "main_icg_en_i3c7", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C8, "main_icg_en_i3c8", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C9, "main_icg_en_i3c9", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C10, "main_icg_en_i3c10", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C11, "main_icg_en_i3c11", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C12, "main_icg_en_i3c12", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C13, "main_icg_en_i3c13", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C14, "main_icg_en_i3c14", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C15, "main_icg_en_i3c15", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_DUALTIMER0, "main_icg_en_dualtimer0",
+		      CLK_IS_CRITICAL, JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_DUALTIMER1, "main_icg_en_dualtimer1",
+		      CLK_IS_CRITICAL, JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_DUALTIMER2, "main_icg_en_dualtimer2",
+		      CLK_IS_CRITICAL, JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_LTPI0, "main_icg_en_ltpi0", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_LTPI1, "main_icg_en_ltpi1", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_DMAC_I2C, "main_icg_en_dmac_i2c",
+		      CLK_IS_CRITICAL, JHB100_PER0CLK_400),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_DMAC_I3C, "main_icg_en_dmac_i3c",
+		      CLK_IS_CRITICAL, JHB100_PER0CLK_400),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_DMAC_UART, "main_icg_en_dmac_uart",
+		      CLK_IS_CRITICAL, JHB100_PER0CLK_400),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SOL4, "main_icg_en_sol4", 0,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SOL5, "main_icg_en_sol5", 0,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SOL6, "main_icg_en_sol6", 0,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SOL7, "main_icg_en_sol7", 0,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SOL8, "main_icg_en_sol8", 0,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SOL9, "main_icg_en_sol9", 0,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SOL10, "main_icg_en_sol10", 0,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SOL11, "main_icg_en_sol11", 0,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SOL12, "main_icg_en_sol12", 0,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SOL13, "main_icg_en_sol13", 0,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SOL14, "main_icg_en_sol14", 0,
+		      JHB100_PER0CLK_200),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C0, "main_icg_en_i2c0", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C1, "main_icg_en_i2c1", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C2, "main_icg_en_i2c2", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C3, "main_icg_en_i2c3", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C4, "main_icg_en_i2c4", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C5, "main_icg_en_i2c5", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C6, "main_icg_en_i2c6", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C7, "main_icg_en_i2c7", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C8, "main_icg_en_i2c8", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C9, "main_icg_en_i2c9", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C10, "main_icg_en_i2c10", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C11, "main_icg_en_i2c11", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C12, "main_icg_en_i2c12", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C13, "main_icg_en_i2c13", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C14, "main_icg_en_i2c14", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C15, "main_icg_en_i2c15", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_WDT0, "main_icg_en_wdt0", 0,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_WDT1, "main_icg_en_wdt1", 0,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_WDT2, "main_icg_en_wdt2", 0,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_WDT3, "main_icg_en_wdt3", 0,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_WDT_EXTERNAL, "main_icg_en_wdt_external", 0,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_UART4, "main_icg_en_uart4", CLK_IS_CRITICAL,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_UART5, "main_icg_en_uart5", CLK_IS_CRITICAL,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_UART6, "main_icg_en_uart6", CLK_IS_CRITICAL,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_UART7, "main_icg_en_uart7", CLK_IS_CRITICAL,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_UART8, "main_icg_en_uart8", CLK_IS_CRITICAL,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_UART9, "main_icg_en_uart9", CLK_IS_CRITICAL,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_UART10, "main_icg_en_uart10", CLK_IS_CRITICAL,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_UART11, "main_icg_en_uart11", CLK_IS_CRITICAL,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_UART12, "main_icg_en_uart12", CLK_IS_CRITICAL,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_UART13, "main_icg_en_uart13", CLK_IS_CRITICAL,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_UART14, "main_icg_en_uart14", CLK_IS_CRITICAL,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_LDO0, "main_icg_en_ldo0", 0,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_LDO1, "main_icg_en_ldo1", 0,
+		      JHB100_PER0CLK_OSC),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SENSORS_PERIPH0, "main_icg_en_sensors_periph0", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SENSORS_DMAC, "main_icg_en_sensors_dmac", 0,
+		      JHB100_PER0CLK_600_DIV6),
+	STARFIVE_GATE(JHB100_PER0CLK_MAIN_ICG_EN_TRNG, "main_icg_en_trng", 0,
+		      JHB100_PER0CLK_200_INIT),
+};
+
+static int jhb100_per0crg_probe(struct platform_device *pdev)
+{
+	struct starfive_clk_priv *priv;
+	unsigned int idx;
+	int ret;
+
+	priv = devm_kzalloc(&pdev->dev,
+			    struct_size(priv, reg, JHB100_PER0CLK_NUM_CLKS),
+			    GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	spin_lock_init(&priv->rmw_lock);
+	priv->num_reg = JHB100_PER0CLK_NUM_CLKS;
+	priv->dev = &pdev->dev;
+	priv->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(priv->base))
+		return PTR_ERR(priv->base);
+
+	for (idx = 0; idx < JHB100_PER0CLK_NUM_CLKS; idx++) {
+		u32 max = jhb100_per0crg_clk_data[idx].max;
+		struct clk_parent_data parents[4] = {};
+		struct clk_init_data init = {
+			.name = jhb100_per0crg_clk_data[idx].name,
+			.ops = starfive_clk_ops(max),
+			.parent_data = parents,
+			.num_parents =
+				((max & STARFIVE_CLK_MUX_MASK) >> STARFIVE_CLK_MUX_SHIFT) + 1,
+			.flags = jhb100_per0crg_clk_data[idx].flags,
+		};
+		struct starfive_clk *clk = &priv->reg[idx];
+		unsigned int i;
+
+		if (!init.name)
+			continue;
+
+		for (i = 0; i < init.num_parents; i++) {
+			unsigned int pidx = jhb100_per0crg_clk_data[idx].parents[i];
+
+			if (pidx < JHB100_PER0CLK_NUM_CLKS)
+				parents[i].hw = &priv->reg[pidx].hw;
+			else if (pidx == JHB100_PER0CLK_200_INIT)
+				parents[i].fw_name = "per0_200_init";
+			else if (pidx == JHB100_PER0CLK_400)
+				parents[i].fw_name = "per0_400";
+			else if (pidx == JHB100_PER0CLK_600)
+				parents[i].fw_name = "per0_600";
+			else if (pidx == JHB100_PER0CLK_OSC)
+				parents[i].fw_name = "osc";
+			else if (pidx == JHB100_PER0CLK_800)
+				parents[i].fw_name = "per0_800";
+			else
+				parents[i].fw_name = "pll6";
+		}
+
+		clk->hw.init = &init;
+		clk->idx = idx;
+		clk->max_div = max & STARFIVE_CLK_DIV_MASK;
+
+		ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
+		if (ret)
+			return ret;
+	}
+
+	ret = devm_of_clk_add_hw_provider(&pdev->dev, starfive_clk_get, priv);
+	if (ret)
+		return ret;
+
+	return jhb100_reset_controller_register(priv, "r-per0", 0);
+}
+
+static const struct of_device_id jhb100_per0crg_match[] = {
+	{ .compatible = "starfive,jhb100-per0crg" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, jhb100_per0crg_match);
+
+static struct platform_driver jhb100_per0crg_driver = {
+	.probe = jhb100_per0crg_probe,
+	.driver = {
+		.name = "clk-starfive-jhb100-per0",
+		.of_match_table = jhb100_per0crg_match,
+	},
+};
+module_platform_driver(jhb100_per0crg_driver);
+
+MODULE_AUTHOR("Changhuang Liang <changhuang.liang@starfivetech.com>");
+MODULE_DESCRIPTION("StarFive JHB100 Peripheral-0 Clock Driver");
+MODULE_LICENSE("GPL");
-- 
2.25.1


^ permalink raw reply related

* [PATCH v1 05/22] dt-bindings: clock: Add StarFive JHB100 System-0 clock and reset generator
From: Changhuang Liang @ 2026-04-02 10:55 UTC (permalink / raw)
  To: Michael Turquette, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Stephen Boyd, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Philipp Zabel, Emil Renner Berthing, Kees Cook,
	Gustavo A . R . Silva, Richard Cochran
  Cc: linux-clk, linux-kernel, devicetree, linux-riscv, linux-hardening,
	netdev, Sia Jee Heng, Hal Feng, Ley Foon Tan, Changhuang Liang
In-Reply-To: <20260402105523.447523-1-changhuang.liang@starfivetech.com>

Add bindings for the System-0 clocks and reset generator (SYS0CRG) on
JHB100 SoC.

Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
---
 .../clock/starfive,jhb100-sys0crg.yaml        | 63 +++++++++++++++++++
 .../dt-bindings/clock/starfive,jhb100-crg.h   | 56 +++++++++++++++++
 .../dt-bindings/reset/starfive,jhb100-crg.h   | 30 +++++++++
 3 files changed, 149 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/starfive,jhb100-sys0crg.yaml
 create mode 100644 include/dt-bindings/clock/starfive,jhb100-crg.h
 create mode 100644 include/dt-bindings/reset/starfive,jhb100-crg.h

diff --git a/Documentation/devicetree/bindings/clock/starfive,jhb100-sys0crg.yaml b/Documentation/devicetree/bindings/clock/starfive,jhb100-sys0crg.yaml
new file mode 100644
index 000000000000..08016a61992c
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/starfive,jhb100-sys0crg.yaml
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/starfive,jhb100-sys0crg.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JHB100 System-0 Clock and Reset Generator
+
+maintainers:
+  - Changhuang Liang <changhuang.liang@starfivetech.com>
+
+properties:
+  compatible:
+    const: starfive,jhb100-sys0crg
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Main Oscillator (25 MHz)
+      - description: PLL0
+      - description: PLL1
+      - description: PLL2
+
+  clock-names:
+    items:
+      - const: osc
+      - const: pll0
+      - const: pll1
+      - const: pll2
+
+  '#clock-cells':
+    const: 1
+    description:
+      See <dt-bindings/clock/starfive,jhb100-crg.h> for valid indices.
+
+  '#reset-cells':
+    const: 1
+    description:
+      See <dt-bindings/reset/starfive-jhb100-crg.h> for valid indices.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - '#clock-cells'
+  - '#reset-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller@13000000 {
+      compatible = "starfive,jhb100-sys0crg";
+      reg = <0x13000000 0x4000>;
+      clocks = <&osc>, <&pll0>, <&pll1>,
+               <&syspll 0>;
+      clock-names = "osc", "pll0", "pll1", "pll2";
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+    };
diff --git a/include/dt-bindings/clock/starfive,jhb100-crg.h b/include/dt-bindings/clock/starfive,jhb100-crg.h
new file mode 100644
index 000000000000..b257cd104a10
--- /dev/null
+++ b/include/dt-bindings/clock/starfive,jhb100-crg.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/*
+ * Copyright (C) 2024 StarFive Technology Co., Ltd.
+ * Author: Changhuang Liang <changhuang.liang@starfivetech.com>
+ *
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_STARFIVE_JHB100_H__
+#define __DT_BINDINGS_CLOCK_STARFIVE_JHB100_H__
+
+/* SYS0CRG clocks */
+#define JHB100_SYS0CLK_BMCPCIERP_600			17
+#define JHB100_SYS0CLK_BMCPCIERP_100			18
+
+#define JHB100_SYS0CLK_PCIE_REF_CML			20
+#define JHB100_SYS0CLK_BMCPCIERP_NCNOC_DATA_INIT	21
+#define JHB100_SYS0CLK_BMCPCIERP_NCNOC_CFG_INIT		22
+#define JHB100_SYS0CLK_BMCPCIERP_NCNOC_TARG		23
+
+#define JHB100_SYS0CLK_BMCPCIERP_PCU			26
+#define JHB100_SYS0CLK_HOSTSS0_100			27
+#define JHB100_SYS0CLK_HOSTSS0_600			28
+#define JHB100_SYS0CLK_HOSTSS0_PHY_SCAN_400		29
+#define JHB100_SYS0CLK_GPIO_ESPI0_66			30
+
+#define JHB100_SYS0CLK_BMCUSB_600			34
+#define JHB100_SYS0CLK_BMCUSB_200			35
+#define JHB100_SYS0CLK_BMCUSB_SCANCLK			36
+#define JHB100_SYS0CLK_BMCUSB_480M_SCANCLK		37
+
+#define JHB100_SYS0CLK_VCE_600				50
+#define JHB100_SYS0CLK_VCE_100				51
+#define JHB100_SYS0CLK_BMCPER2_600			52
+#define JHB100_SYS0CLK_BMCPER2_100			53
+#define JHB100_SYS0CLK_BMCPER2_400			54
+#define JHB100_SYS0CLK_BMCPER2_125			55
+
+#define JHB100_SYS0CLK_HOSTSS1_600			58
+#define JHB100_SYS0CLK_HOSTSS1_PHY_SCAN_400		59
+#define JHB100_SYS0CLK_HOSTSS1_PHY_SCAN_400_ICG_BUF	60
+#define JHB100_SYS0CLK_NPU_600				61
+#define JHB100_SYS0CLK_VOUT_600				62
+#define JHB100_SYS0CLK_VOUT_AUX				63
+
+#define JHB100_SYS0CLK_BMCPER3_600			65
+#define JHB100_SYS0CLK_HOSTUSB_600			66
+#define JHB100_SYS0CLK_HOSTUSBCMN_480			67
+#define JHB100_SYS0CLK_BMCPER1_600			68
+#define JHB100_SYS0CLK_BMCPER1_800			69
+#define JHB100_SYS0CLK_BMCPER0_600			70
+#define JHB100_SYS0CLK_BMCPER0_400			71
+#define JHB100_SYS0CLK_BMCPER0_800			72
+#define JHB100_SYS0CLK_GPU0_600				73
+#define JHB100_SYS0CLK_GPU1_600				74
+
+#endif /* __DT_BINDINGS_CLOCK_STARFIVE_JHB100_H__ */
diff --git a/include/dt-bindings/reset/starfive,jhb100-crg.h b/include/dt-bindings/reset/starfive,jhb100-crg.h
new file mode 100644
index 000000000000..71affdcdf733
--- /dev/null
+++ b/include/dt-bindings/reset/starfive,jhb100-crg.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/*
+ * Copyright (C) 2024 StarFive Technology Co., Ltd.
+ * Author: Changhuang Liang <changhuang.liang@starfivetech.com>
+ *
+ */
+
+#ifndef __DT_BINDINGS_RESET_STARFIVE_JHB100_CRG_H__
+#define __DT_BINDINGS_RESET_STARFIVE_JHB100_CRG_H__
+
+/* SYS0CRG resets */
+#define JHB100_SYS0RST_RESOURCE_ARB					0
+
+#define JHB100_SYS0RST_SYS0_IOMUX_PRESETN				3
+#define JHB100_SYS0RST_SYS0H_IOMUX_PRESETN				4
+#define JHB100_SYS0RST_RST_ADAPTOR_TIMEOUT_RSTN				5
+
+#define JHB100_SYS0RST_BMCPCIERP_RSTN_BUS				14
+#define JHB100_SYS0RST_BMCPCIERP_RSTN_CRG				15
+#define JHB100_SYS0RST_HOSTSS0_RSTN_BUS_ESPI				16
+#define JHB100_SYS0RST_HOSTSS0_RSTN_BUS_PCIE				17
+#define JHB100_SYS0RST_HOSTSS0_RSTN_CRG					18
+#define JHB100_SYS0RST_BMCPERIPH2_RSTN_CRG				19
+#define JHB100_SYS0RST_BMCPERIPH2_RSTN_BUS				20
+#define JHB100_SYS0RST_VCE_RSTN_CRG					21
+#define JHB100_SYS0RST_VCE_RSTN_BUS					22
+#define JHB100_SYS0RST_BMCUSB_RSTN_BUS					23
+#define JHB100_SYS0RST_BMCUSB_RSTN_CRG					24
+
+#endif /* __DT_BINDINGS_RESET_STARFIVE_JHB100_CRG_H__ */
-- 
2.25.1


^ permalink raw reply related


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