AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/07/22 09:04 flow patch-triage
0m Args:
null

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch introduces a hardware-specific platform driver for the Renesas R-Car Gen4 gPTP timer. The driver requires specific hardware resources, including MMIO regions and SoC-specific clocks, to successfully probe and execute. These resources are not available in generic virtualized environments like GCE or QEMU, making the code unreachable for fuzzing.",
  "WorthFuzzing": false
}

1/1 2026/07/22 09:04 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit 2bb41ea3002dcf9fccd4427f3171a31a8e68f1dc\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Wed Jul 22 09:04:29 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/Documentation/devicetree/bindings/ptp/renesas,rcar-gen4-gptp.yaml b/Documentation/devicetree/bindings/ptp/renesas,rcar-gen4-gptp.yaml\nnew file mode 100644\nindex 00000000000000..3edd64d400387d\n--- /dev/null\n+++ b/Documentation/devicetree/bindings/ptp/renesas,rcar-gen4-gptp.yaml\n@@ -0,0 +1,64 @@\n+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause\n+# Copyright (C) 2026 Renesas Electronics Corp.\n+# Copyright (C) 2026 Niklas Söderlund \u003cniklas.soderlund@ragnatech.se\u003e\n+%YAML 1.2\n+---\n+$id: http://devicetree.org/schemas/ptp/renesas,rcar-gen4-gptp.yaml#\n+$schema: http://devicetree.org/meta-schemas/core.yaml#\n+\n+title: Renesas R-Car Gen4 gPTP timer\n+\n+maintainers:\n+  - Niklas Söderlund \u003cniklas.soderlund@ragnatech.se\u003e\n+\n+description:\n+  The R-Car Gen4 gPTP timer enables accurate synchronization of the clock in\n+  the control system. The timer is system-wide and used by different Ethernet\n+  devices on each Gen4 platform.\n+\n+    - On R-Car S4 it is shared between RSWITCH and RAVB.\n+    - On R-Car V4H it is shared between RTSN and RAVB.\n+    - On R-Car V4M it is only used by RAVB.\n+\n+properties:\n+  compatible:\n+    items:\n+      - enum:\n+          - renesas,r8a779f0-gptp # S4-8\n+          - renesas,r8a779g0-gptp # V4H\n+          - renesas,r8a779h0-gptp # V4M\n+      - const: renesas,rcar-gen4-gptp\n+\n+  reg:\n+    maxItems: 1\n+\n+  clocks:\n+    maxItems: 1\n+\n+  power-domains:\n+    maxItems: 1\n+\n+  resets:\n+    maxItems: 1\n+\n+required:\n+  - compatible\n+  - reg\n+  - clocks\n+  - power-domains\n+  - resets\n+\n+additionalProperties: false\n+\n+examples:\n+  - |\n+    #include \u003cdt-bindings/clock/r8a779g0-cpg-mssr.h\u003e\n+    #include \u003cdt-bindings/power/r8a779g0-sysc.h\u003e\n+\n+    ptp@e6449000 {\n+            compatible = \"renesas,r8a779g0-gptp\", \"renesas,rcar-gen4-gptp\";\n+            reg = \u003c0xe6449000 0x500\u003e;\n+            clocks = \u003c\u0026cpg CPG_MOD 2723\u003e;\n+            power-domains = \u003c\u0026sysc R8A779G0_PD_ALWAYS_ON\u003e;\n+            resets = \u003c\u0026cpg 2723\u003e;\n+    };\ndiff --git a/MAINTAINERS b/MAINTAINERS\nindex 6940aa3d498b99..ed54ac3cf550b8 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -22914,6 +22914,13 @@ S:\tMaintained\n F:\tDocumentation/devicetree/bindings/mtd/renesas-nandc.yaml\n F:\tdrivers/mtd/nand/raw/renesas-nand-controller.c\n \n+RENESAS R-CAR GEN4 GPTP DRIVER\n+M:\tNiklas Söderlund \u003cniklas.soderlund@ragnatech.se\u003e\n+L:\tlinux-renesas-soc@vger.kernel.org\n+S:\tSupported\n+F:\tDocumentation/devicetree/bindings/ptp/renesas,rcar-gen4-gptp.yaml\n+F:\tdrivers/ptp/ptp_rcar_gen4.c\n+\n RENESAS R-CAR GYROADC DRIVER\n M:\tMarek Vasut \u003cmarek.vasut+renesas@mailbox.org\u003e\n L:\tlinux-iio@vger.kernel.org\ndiff --git a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi\nindex 82a7278836e57a..b9b860ef70351b 100644\n--- a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi\n+++ b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi\n@@ -589,6 +589,15 @@ tmu4: timer@ffc00000 {\n \t\t\tstatus = \"disabled\";\n \t\t};\n \n+\t\tgptp: ptp@e6449000 {\n+\t\t\tcompatible = \"renesas,r8a779g0-gptp\", \"renesas,rcar-gen4-gptp\";\n+\t\t\treg = \u003c0 0xe6449000 0 0x500\u003e;\n+\t\t\tclocks = \u003c\u0026cpg CPG_MOD 2723\u003e;\n+\t\t\tpower-domains = \u003c\u0026sysc R8A779G0_PD_ALWAYS_ON\u003e;\n+\t\t\tresets = \u003c\u0026cpg 2723\u003e;\n+\t\t\tstatus = \"disabled\";\n+\t\t};\n+\n \t\ttsn0: ethernet@e6460000 {\n \t\t\tcompatible = \"renesas,r8a779g0-ethertsn\", \"renesas,rcar-gen4-ethertsn\";\n \t\t\treg = \u003c0 0xe6460000 0 0x7000\u003e,\ndiff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig\nindex b93640ca08b728..3593fd9da92acd 100644\n--- a/drivers/ptp/Kconfig\n+++ b/drivers/ptp/Kconfig\n@@ -263,4 +263,16 @@ config PTP_NETC_V4_TIMER\n \t  synchronization. It also supports periodic output signal (e.g. PPS)\n \t  and external trigger timestamping.\n \n+config PTP_RCAR_GEN4\n+\ttristate \"Renesas R-Car Gen4 PTP Driver\"\n+\tdepends on ARCH_RENESAS || COMPILE_TEST\n+\tdepends on PTP_1588_CLOCK\n+\thelp\n+\t  This driver adds support for using the Renesas R-Car Gen4 gPTP timer\n+\t  as a PTP clock, the clock can then be used by Gen4 Ethernet drivers\n+\t  for PTP time synchronization.\n+\n+\t  To compile this driver as a module, choose M here: the module\n+\t  will be called ptp_rcar_gen4.\n+\n endmenu\ndiff --git a/drivers/ptp/Makefile b/drivers/ptp/Makefile\nindex bdc47e284f14e7..0464a586bed29b 100644\n--- a/drivers/ptp/Makefile\n+++ b/drivers/ptp/Makefile\n@@ -22,3 +22,4 @@ obj-$(CONFIG_PTP_1588_CLOCK_OCP)\t+= ptp_ocp.o\n obj-$(CONFIG_PTP_DFL_TOD)\t\t+= ptp_dfl_tod.o\n obj-$(CONFIG_PTP_S390)\t\t\t+= ptp_s390.o\n obj-$(CONFIG_PTP_NETC_V4_TIMER)\t\t+= ptp_netc.o\n+obj-$(CONFIG_PTP_RCAR_GEN4)\t\t+= ptp_rcar_gen4.o\ndiff --git a/drivers/ptp/ptp_rcar_gen4.c b/drivers/ptp/ptp_rcar_gen4.c\nnew file mode 100644\nindex 00000000000000..8072d5f2b72ddd\n--- /dev/null\n+++ b/drivers/ptp/ptp_rcar_gen4.c\n@@ -0,0 +1,225 @@\n+// SPDX-License-Identifier: GPL-2.0\n+/* Renesas R-Car Gen4 gPTP device driver\n+ *\n+ * Copyright (C) 2026 Renesas Electronics Corporation\n+ * Copyright (C) 2026 Niklas Söderlund \u003cniklas.soderlund@ragnatech.se\u003e\n+ */\n+\n+#include \u003clinux/clk.h\u003e\n+#include \u003clinux/err.h\u003e\n+#include \u003clinux/io.h\u003e\n+#include \u003clinux/module.h\u003e\n+#include \u003clinux/platform_device.h\u003e\n+#include \u003clinux/pm_runtime.h\u003e\n+#include \u003clinux/ptp_clock_kernel.h\u003e\n+#include \u003clinux/types.h\u003e\n+\n+#define PTPTMEC_REG\t\t0x0010\n+#define PTPTMDC_REG\t\t0x0014\n+#define PTPTIVC0_REG\t\t0x0020\n+#define PTPTOVC00_REG\t\t0x0030\n+#define PTPTOVC10_REG\t\t0x0034\n+#define PTPTOVC20_REG\t\t0x0038\n+#define PTPGPTPTM00_REG\t\t0x0050\n+#define PTPGPTPTM10_REG\t\t0x0054\n+#define PTPGPTPTM20_REG\t\t0x0058\n+\n+struct ptp_rcar_gen4_priv {\n+\tvoid __iomem *base;\n+\tstruct clk *clk;\n+\n+\tstruct ptp_clock *clock;\n+\tstruct ptp_clock_info info;\n+\n+\tspinlock_t lock;\t/* Registers access. */\n+\ts64 default_addend;\n+};\n+\n+#define ptp_to_priv(ptp) container_of(ptp, struct ptp_rcar_gen4_priv, info)\n+\n+static int ptp_rcar_gen4_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)\n+{\n+\tstruct ptp_rcar_gen4_priv *priv = ptp_to_priv(ptp);\n+\ts64 addend = priv-\u003edefault_addend;\n+\tbool neg_adj = scaled_ppm \u003c 0;\n+\tunsigned long flags;\n+\ts64 diff;\n+\n+\tif (neg_adj)\n+\t\tscaled_ppm = -scaled_ppm;\n+\tdiff = div_s64(addend * scaled_ppm_to_ppb(scaled_ppm), NSEC_PER_SEC);\n+\taddend = neg_adj ? addend - diff : addend + diff;\n+\n+\tspin_lock_irqsave(\u0026priv-\u003elock, flags);\n+\tiowrite32(addend, priv-\u003ebase + PTPTIVC0_REG);\n+\tspin_unlock_irqrestore(\u0026priv-\u003elock, flags);\n+\n+\treturn 0;\n+}\n+\n+static void _ptp_rcar_gen4_gettime(struct ptp_clock_info *ptp,\n+\t\t\t\t   struct timespec64 *ts)\n+{\n+\tstruct ptp_rcar_gen4_priv *priv = ptp_to_priv(ptp);\n+\n+\tlockdep_assert_held(\u0026priv-\u003elock);\n+\n+\tts-\u003etv_nsec = ioread32(priv-\u003ebase + PTPGPTPTM00_REG);\n+\tts-\u003etv_sec = ioread32(priv-\u003ebase + PTPGPTPTM10_REG) |\n+\t\t((s64)ioread32(priv-\u003ebase + PTPGPTPTM20_REG) \u003c\u003c 32);\n+}\n+\n+static int ptp_rcar_gen4_gettime(struct ptp_clock_info *ptp,\n+\t\t\t\t struct timespec64 *ts)\n+{\n+\tstruct ptp_rcar_gen4_priv *priv = ptp_to_priv(ptp);\n+\tunsigned long flags;\n+\n+\tspin_lock_irqsave(\u0026priv-\u003elock, flags);\n+\t_ptp_rcar_gen4_gettime(ptp, ts);\n+\tspin_unlock_irqrestore(\u0026priv-\u003elock, flags);\n+\n+\treturn 0;\n+}\n+\n+static void _ptp_rcar_gen4_settime(struct ptp_clock_info *ptp,\n+\t\t\t\t   const struct timespec64 *ts)\n+{\n+\tstruct ptp_rcar_gen4_priv *priv = ptp_to_priv(ptp);\n+\n+\tlockdep_assert_held(\u0026priv-\u003elock);\n+\n+\tiowrite32(1, priv-\u003ebase + PTPTMDC_REG);\n+\tiowrite32(0, priv-\u003ebase + PTPTOVC20_REG);\n+\tiowrite32(0, priv-\u003ebase + PTPTOVC10_REG);\n+\tiowrite32(0, priv-\u003ebase + PTPTOVC00_REG);\n+\tiowrite32(1, priv-\u003ebase + PTPTMEC_REG);\n+\tiowrite32(ts-\u003etv_sec \u003e\u003e 32, priv-\u003ebase + PTPTOVC20_REG);\n+\tiowrite32(ts-\u003etv_sec, priv-\u003ebase + PTPTOVC10_REG);\n+\tiowrite32(ts-\u003etv_nsec, priv-\u003ebase + PTPTOVC00_REG);\n+}\n+\n+static int ptp_rcar_gen4_settime(struct ptp_clock_info *ptp,\n+\t\t\t\t const struct timespec64 *ts)\n+{\n+\tstruct ptp_rcar_gen4_priv *priv = ptp_to_priv(ptp);\n+\tunsigned long flags;\n+\n+\tspin_lock_irqsave(\u0026priv-\u003elock, flags);\n+\t_ptp_rcar_gen4_settime(ptp, ts);\n+\tspin_unlock_irqrestore(\u0026priv-\u003elock, flags);\n+\n+\treturn 0;\n+}\n+\n+static int ptp_rcar_gen4_adjtime(struct ptp_clock_info *ptp, s64 delta)\n+{\n+\tstruct ptp_rcar_gen4_priv *priv = ptp_to_priv(ptp);\n+\tstruct timespec64 ts;\n+\tunsigned long flags;\n+\ts64 now;\n+\n+\tspin_lock_irqsave(\u0026priv-\u003elock, flags);\n+\t_ptp_rcar_gen4_gettime(ptp, \u0026ts);\n+\tnow = ktime_to_ns(timespec64_to_ktime(ts));\n+\tts = ns_to_timespec64(now + delta);\n+\t_ptp_rcar_gen4_settime(ptp, \u0026ts);\n+\tspin_unlock_irqrestore(\u0026priv-\u003elock, flags);\n+\n+\treturn 0;\n+}\n+\n+static struct ptp_clock_info ptp_rcar_gen4_info = {\n+\t.owner = THIS_MODULE,\n+\t.name = \"R-Car Gen4 gPTP\",\n+\t.max_adj = 50000000,\n+\t.adjfine = ptp_rcar_gen4_adjfine,\n+\t.adjtime = ptp_rcar_gen4_adjtime,\n+\t.gettime64 = ptp_rcar_gen4_gettime,\n+\t.settime64 = ptp_rcar_gen4_settime,\n+};\n+\n+static int ptp_rcar_gen4_probe(struct platform_device *pdev)\n+{\n+\tstruct ptp_rcar_gen4_priv *priv;\n+\tstruct device *dev = \u0026pdev-\u003edev;\n+\tunsigned long rate;\n+\n+\tpriv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);\n+\tif (!priv)\n+\t\treturn -ENOMEM;\n+\n+\tplatform_set_drvdata(pdev, priv);\n+\n+\tpriv-\u003ebase = devm_platform_ioremap_resource(pdev, 0);\n+\tif (IS_ERR(priv-\u003ebase))\n+\t\treturn PTR_ERR(priv-\u003ebase);\n+\n+\tpriv-\u003eclk = devm_clk_get(dev, NULL);\n+\tif (IS_ERR(priv-\u003eclk))\n+\t\treturn PTR_ERR(priv-\u003eclk);\n+\n+\trate = clk_get_rate(priv-\u003eclk);\n+\tif (!rate)\n+\t\treturn -ENODEV;\n+\n+\tspin_lock_init(\u0026priv-\u003elock);\n+\n+\tpriv-\u003einfo = ptp_rcar_gen4_info;\n+\n+\t/* Default timer increment in ns.\n+\t * bit[31:27] - integer\n+\t * bit[26:0]  - decimal\n+\t * increment[ns] = perid[ns] * 2^27 =\u003e (1ns * 2^27) / rate[hz]\n+\t */\n+\n+\tpriv-\u003edefault_addend = div_s64(1000000000LL \u003c\u003c 27, rate);\n+\n+\tpm_runtime_enable(dev);\n+\tpm_runtime_get_sync(dev);\n+\n+\tiowrite32(priv-\u003edefault_addend, priv-\u003ebase + PTPTIVC0_REG);\n+\tiowrite32(1, priv-\u003ebase + PTPTMEC_REG);\n+\n+\tpriv-\u003eclock = ptp_clock_register(\u0026priv-\u003einfo, dev);\n+\tif (IS_ERR(priv-\u003eclock)) {\n+\t\tpm_runtime_put_sync(dev);\n+\t\tpm_runtime_disable(dev);\n+\t\treturn PTR_ERR(priv-\u003eclock);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void ptp_rcar_gen4_remove(struct platform_device *pdev)\n+{\n+\tstruct ptp_rcar_gen4_priv *priv = platform_get_drvdata(pdev);\n+\tstruct device *dev = \u0026pdev-\u003edev;\n+\n+\tptp_clock_unregister(priv-\u003eclock);\n+\n+\tiowrite32(1, priv-\u003ebase + PTPTMDC_REG);\n+\n+\tpm_runtime_put_sync(dev);\n+\tpm_runtime_disable(dev);\n+}\n+\n+static const struct of_device_id ptp_rcar_gen4_of_match[] = {\n+\t{ .compatible = \"renesas,rcar-gen4-gptp\", },\n+\t{ /* Sentinel */ },\n+};\n+MODULE_DEVICE_TABLE(of, ptp_rcar_gen4_of_match);\n+\n+static struct platform_driver ptp_rcar_gen4_driver = {\n+\t.driver = {\n+\t\t.name = \"ptp-rcar-gen4\",\n+\t\t.of_match_table = ptp_rcar_gen4_of_match,\n+\t},\n+\t.probe    = ptp_rcar_gen4_probe,\n+\t.remove   = ptp_rcar_gen4_remove,\n+};\n+module_platform_driver(ptp_rcar_gen4_driver);\n+\n+MODULE_AUTHOR(\"Niklas Söderlund\");\n+MODULE_DESCRIPTION(\"Renesas R-Car Gen4 gPTP driver\");\n+MODULE_LICENSE(\"GPL\");\n"
}

2/1 2026/07/22 09:04 agent patch-evaluator
0m Model:
best-expensive

Args:
null

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch introduces a hardware-specific platform driver for the Renesas R-Car Gen4 gPTP timer. The driver requires specific hardware resources, including MMIO regions and SoC-specific clocks, to successfully probe and execute. These resources are not available in generic virtualized environments like GCE or QEMU, making the code unreachable for fuzzing.",
  "WorthFuzzing": false
}

Instruction:
You are an expert Linux kernel maintainer.
Your job is to review a provided patch series and determine
if it makes functional changes to the kernel that should be fuzzed.

IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively
use your code access tools to examine the actual source code and confirm any assumptions.

Return WorthFuzzing=false if the patch only contains:
- Modifications to Documentation/, Kconfig files, or code comments.
- Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints.
- Changes to numeric constants or macros that do not functionally alter execution flow.
- Code paths that are impossible to reach in virtualized environments like GCE or QEMU,
even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim).

If it modifies reachable core kernel logic, drivers, or architectures, use your code search
tools to verify the code can be executed, then return WorthFuzzing=true.

When returning WorthFuzzing=true, you MUST ALSO:
1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols.
   Avoid listing generic hot-path functions to prevent skewed test distributions.
2. Identify any specific CONFIG_ options required to properly test this new/modified feature.
   Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions.
   Do not list too generic configs (we already have them enabled). Only list those that
   specifically cover the modified code. List them in the EnableConfigs output array,
   and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.


Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.

Prompt:
For your convenience, here is the diff of the changes:
commit 2bb41ea3002dcf9fccd4427f3171a31a8e68f1dc
Author: syz-cluster <triage@syzkaller.com>
Date:   Wed Jul 22 09:04:29 2026 +0000

    syz-cluster: applied patch under review

diff --git a/Documentation/devicetree/bindings/ptp/renesas,rcar-gen4-gptp.yaml b/Documentation/devicetree/bindings/ptp/renesas,rcar-gen4-gptp.yaml
new file mode 100644
index 00000000000000..3edd64d400387d
--- /dev/null
+++ b/Documentation/devicetree/bindings/ptp/renesas,rcar-gen4-gptp.yaml
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+# Copyright (C) 2026 Renesas Electronics Corp.
+# Copyright (C) 2026 Niklas Söderlund <niklas.soderlund@ragnatech.se>
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/ptp/renesas,rcar-gen4-gptp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas R-Car Gen4 gPTP timer
+
+maintainers:
+  - Niklas Söderlund <niklas.soderlund@ragnatech.se>
+
+description:
+  The R-Car Gen4 gPTP timer enables accurate synchronization of the clock in
+  the control system. The timer is system-wide and used by different Ethernet
+  devices on each Gen4 platform.
+
+    - On R-Car S4 it is shared between RSWITCH and RAVB.
+    - On R-Car V4H it is shared between RTSN and RAVB.
+    - On R-Car V4M it is only used by RAVB.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - renesas,r8a779f0-gptp # S4-8
+          - renesas,r8a779g0-gptp # V4H
+          - renesas,r8a779h0-gptp # V4M
+      - const: renesas,rcar-gen4-gptp
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - power-domains
+  - resets
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/r8a779g0-cpg-mssr.h>
+    #include <dt-bindings/power/r8a779g0-sysc.h>
+
+    ptp@e6449000 {
+            compatible = "renesas,r8a779g0-gptp", "renesas,rcar-gen4-gptp";
+            reg = <0xe6449000 0x500>;
+            clocks = <&cpg CPG_MOD 2723>;
+            power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>;
+            resets = <&cpg 2723>;
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 6940aa3d498b99..ed54ac3cf550b8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22914,6 +22914,13 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/mtd/renesas-nandc.yaml
 F:	drivers/mtd/nand/raw/renesas-nand-controller.c
 
+RENESAS R-CAR GEN4 GPTP DRIVER
+M:	Niklas Söderlund <niklas.soderlund@ragnatech.se>
+L:	linux-renesas-soc@vger.kernel.org
+S:	Supported
+F:	Documentation/devicetree/bindings/ptp/renesas,rcar-gen4-gptp.yaml
+F:	drivers/ptp/ptp_rcar_gen4.c
+
 RENESAS R-CAR GYROADC DRIVER
 M:	Marek Vasut <marek.vasut+renesas@mailbox.org>
 L:	linux-iio@vger.kernel.org
diff --git a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi
index 82a7278836e57a..b9b860ef70351b 100644
--- a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi
@@ -589,6 +589,15 @@ tmu4: timer@ffc00000 {
 			status = "disabled";
 		};
 
+		gptp: ptp@e6449000 {
+			compatible = "renesas,r8a779g0-gptp", "renesas,rcar-gen4-gptp";
+			reg = <0 0xe6449000 0 0x500>;
+			clocks = <&cpg CPG_MOD 2723>;
+			power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>;
+			resets = <&cpg 2723>;
+			status = "disabled";
+		};
+
 		tsn0: ethernet@e6460000 {
 			compatible = "renesas,r8a779g0-ethertsn", "renesas,rcar-gen4-ethertsn";
 			reg = <0 0xe6460000 0 0x7000>,
diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig
index b93640ca08b728..3593fd9da92acd 100644
--- a/drivers/ptp/Kconfig
+++ b/drivers/ptp/Kconfig
@@ -263,4 +263,16 @@ config PTP_NETC_V4_TIMER
 	  synchronization. It also supports periodic output signal (e.g. PPS)
 	  and external trigger timestamping.
 
+config PTP_RCAR_GEN4
+	tristate "Renesas R-Car Gen4 PTP Driver"
+	depends on ARCH_RENESAS || COMPILE_TEST
+	depends on PTP_1588_CLOCK
+	help
+	  This driver adds support for using the Renesas R-Car Gen4 gPTP timer
+	  as a PTP clock, the clock can then be used by Gen4 Ethernet drivers
+	  for PTP time synchronization.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called ptp_rcar_gen4.
+
 endmenu
diff --git a/drivers/ptp/Makefile b/drivers/ptp/Makefile
index bdc47e284f14e7..0464a586bed29b 100644
--- a/drivers/ptp/Makefile
+++ b/drivers/ptp/Makefile
@@ -22,3 +22,4 @@ obj-$(CONFIG_PTP_1588_CLOCK_OCP)	+= ptp_ocp.o
 obj-$(CONFIG_PTP_DFL_TOD)		+= ptp_dfl_tod.o
 obj-$(CONFIG_PTP_S390)			+= ptp_s390.o
 obj-$(CONFIG_PTP_NETC_V4_TIMER)		+= ptp_netc.o
+obj-$(CONFIG_PTP_RCAR_GEN4)		+= ptp_rcar_gen4.o
diff --git a/drivers/ptp/ptp_rcar_gen4.c b/drivers/ptp/ptp_rcar_gen4.c
new file mode 100644
index 00000000000000..8072d5f2b72ddd
--- /dev/null
+++ b/drivers/ptp/ptp_rcar_gen4.c
@@ -0,0 +1,225 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Renesas R-Car Gen4 gPTP device driver
+ *
+ * Copyright (C) 2026 Renesas Electronics Corporation
+ * Copyright (C) 2026 Niklas Söderlund <niklas.soderlund@ragnatech.se>
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/ptp_clock_kernel.h>
+#include <linux/types.h>
+
+#define PTPTMEC_REG		0x0010
+#define PTPTMDC_REG		0x0014
+#define PTPTIVC0_REG		0x0020
+#define PTPTOVC00_REG		0x0030
+#define PTPTOVC10_REG		0x0034
+#define PTPTOVC20_REG		0x0038
+#define PTPGPTPTM00_REG		0x0050
+#define PTPGPTPTM10_REG		0x0054
+#define PTPGPTPTM20_REG		0x0058
+
+struct ptp_rcar_gen4_priv {
+	void __iomem *base;
+	struct clk *clk;
+
+	struct ptp_clock *clock;
+	struct ptp_clock_info info;
+
+	spinlock_t lock;	/* Registers access. */
+	s64 default_addend;
+};
+
+#define ptp_to_priv(ptp) container_of(ptp, struct ptp_rcar_gen4_priv, info)
+
+static int ptp_rcar_gen4_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
+{
+	struct ptp_rcar_gen4_priv *priv = ptp_to_priv(ptp);
+	s64 addend = priv->default_addend;
+	bool neg_adj = scaled_ppm < 0;
+	unsigned long flags;
+	s64 diff;
+
+	if (neg_adj)
+		scaled_ppm = -scaled_ppm;
+	diff = div_s64(addend * scaled_ppm_to_ppb(scaled_ppm), NSEC_PER_SEC);
+	addend = neg_adj ? addend - diff : addend + diff;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	iowrite32(addend, priv->base + PTPTIVC0_REG);
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return 0;
+}
+
+static void _ptp_rcar_gen4_gettime(struct ptp_clock_info *ptp,
+				   struct timespec64 *ts)
+{
+	struct ptp_rcar_gen4_priv *priv = ptp_to_priv(ptp);
+
+	lockdep_assert_held(&priv->lock);
+
+	ts->tv_nsec = ioread32(priv->base + PTPGPTPTM00_REG);
+	ts->tv_sec = ioread32(priv->base + PTPGPTPTM10_REG) |
+		((s64)ioread32(priv->base + PTPGPTPTM20_REG) << 32);
+}
+
+static int ptp_rcar_gen4_gettime(struct ptp_clock_info *ptp,
+				 struct timespec64 *ts)
+{
+	struct ptp_rcar_gen4_priv *priv = ptp_to_priv(ptp);
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	_ptp_rcar_gen4_gettime(ptp, ts);
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return 0;
+}
+
+static void _ptp_rcar_gen4_settime(struct ptp_clock_info *ptp,
+				   const struct timespec64 *ts)
+{
+	struct ptp_rcar_gen4_priv *priv = ptp_to_priv(ptp);
+
+	lockdep_assert_held(&priv->lock);
+
+	iowrite32(1, priv->base + PTPTMDC_REG);
+	iowrite32(0, priv->base + PTPTOVC20_REG);
+	iowrite32(0, priv->base + PTPTOVC10_REG);
+	iowrite32(0, priv->base + PTPTOVC00_REG);
+	iowrite32(1, priv->base + PTPTMEC_REG);
+	iowrite32(ts->tv_sec >> 32, priv->base + PTPTOVC20_REG);
+	iowrite32(ts->tv_sec, priv->base + PTPTOVC10_REG);
+	iowrite32(ts->tv_nsec, priv->base + PTPTOVC00_REG);
+}
+
+static int ptp_rcar_gen4_settime(struct ptp_clock_info *ptp,
+				 const struct timespec64 *ts)
+{
+	struct ptp_rcar_gen4_priv *priv = ptp_to_priv(ptp);
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	_ptp_rcar_gen4_settime(ptp, ts);
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return 0;
+}
+
+static int ptp_rcar_gen4_adjtime(struct ptp_clock_info *ptp, s64 delta)
+{
+	struct ptp_rcar_gen4_priv *priv = ptp_to_priv(ptp);
+	struct timespec64 ts;
+	unsigned long flags;
+	s64 now;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	_ptp_rcar_gen4_gettime(ptp, &ts);
+	now = ktime_to_ns(timespec64_to_ktime(ts));
+	ts = ns_to_timespec64(now + delta);
+	_ptp_rcar_gen4_settime(ptp, &ts);
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return 0;
+}
+
+static struct ptp_clock_info ptp_rcar_gen4_info = {
+	.owner = THIS_MODULE,
+	.name = "R-Car Gen4 gPTP",
+	.max_adj = 50000000,
+	.adjfine = ptp_rcar_gen4_adjfine,
+	.adjtime = ptp_rcar_gen4_adjtime,
+	.gettime64 = ptp_rcar_gen4_gettime,
+	.settime64 = ptp_rcar_gen4_settime,
+};
+
+static int ptp_rcar_gen4_probe(struct platform_device *pdev)
+{
+	struct ptp_rcar_gen4_priv *priv;
+	struct device *dev = &pdev->dev;
+	unsigned long rate;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, priv);
+
+	priv->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(priv->base))
+		return PTR_ERR(priv->base);
+
+	priv->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(priv->clk))
+		return PTR_ERR(priv->clk);
+
+	rate = clk_get_rate(priv->clk);
+	if (!rate)
+		return -ENODEV;
+
+	spin_lock_init(&priv->lock);
+
+	priv->info = ptp_rcar_gen4_info;
+
+	/* Default timer increment in ns.
+	 * bit[31:27] - integer
+	 * bit[26:0]  - decimal
+	 * increment[ns] = perid[ns] * 2^27 => (1ns * 2^27) / rate[hz]
+	 */
+
+	priv->default_addend = div_s64(1000000000LL << 27, rate);
+
+	pm_runtime_enable(dev);
+	pm_runtime_get_sync(dev);
+
+	iowrite32(priv->default_addend, priv->base + PTPTIVC0_REG);
+	iowrite32(1, priv->base + PTPTMEC_REG);
+
+	priv->clock = ptp_clock_register(&priv->info, dev);
+	if (IS_ERR(priv->clock)) {
+		pm_runtime_put_sync(dev);
+		pm_runtime_disable(dev);
+		return PTR_ERR(priv->clock);
+	}
+
+	return 0;
+}
+
+static void ptp_rcar_gen4_remove(struct platform_device *pdev)
+{
+	struct ptp_rcar_gen4_priv *priv = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+
+	ptp_clock_unregister(priv->clock);
+
+	iowrite32(1, priv->base + PTPTMDC_REG);
+
+	pm_runtime_put_sync(dev);
+	pm_runtime_disable(dev);
+}
+
+static const struct of_device_id ptp_rcar_gen4_of_match[] = {
+	{ .compatible = "renesas,rcar-gen4-gptp", },
+	{ /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, ptp_rcar_gen4_of_match);
+
+static struct platform_driver ptp_rcar_gen4_driver = {
+	.driver = {
+		.name = "ptp-rcar-gen4",
+		.of_match_table = ptp_rcar_gen4_of_match,
+	},
+	.probe    = ptp_rcar_gen4_probe,
+	.remove   = ptp_rcar_gen4_remove,
+};
+module_platform_driver(ptp_rcar_gen4_driver);
+
+MODULE_AUTHOR("Niklas Söderlund");
+MODULE_DESCRIPTION("Renesas R-Car Gen4 gPTP driver");
+MODULE_LICENSE("GPL");

3/2 2026/07/22 09:04 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 6726
							output: 103
							thoughts: 954
						

Thoughts:
**Assessing the Fuzzability of the Renesas R-Car Gen4 gPTP Driver**

Okay, so there's a new PTP driver, `ptp_rcar_gen4.c`, for the Renesas R-Car Gen4 gPTP timer. My initial thought is, can we actually reach this thing in a virtualized environment like GCE or QEMU? These platform drivers, being specific to an SoC like the R-Car, are usually a no-go unless we're dealing with an emulator or something generically instantiable. I wonder, can we inject this driver via a device tree overlay? It matches `"renesas,rcar-gen4-gptp"`... so, if we could inject a platform device, maybe, just maybe, it could be probed.

But, a quick look reveals it uses `devm_platform_ioremap_resource` and, crucially, `devm_clk_get(dev, NULL)`.  In order to get this working with a faked device tree node, we'd need to provide a valid clock and memory region. Syzkaller *can* inject platform devices through `syz_devres` and such, but hardware-specific drivers that read/write to MMIO registers and require clocks are typically considered unreachable in a generic virtualized setting. They'll just crash when trying to access invalid MMIO or fail to probe due to missing clocks.

Wait... syzkaller *does* have some platform driver fuzzing support, generating fake devices, but it's pretty limited.  So, can we actually fuzz `PTP_RCAR_GEN4`? If the driver *only* uses `ioread32`/`iowrite32` on a mapped resource, syzkaller creating a dummy memory resource *might* let it probe, and then we could fuzz the PTP ioctls. But that `devm_clk_get` is a major roadblock.  Let's dig into `ptp_rcar_gen4_probe`.

```c
	priv->clk = devm_clk_get(dev, NULL);
	if (IS_ERR(priv->clk))
		return PTR_ERR(priv->clk);

	rate = clk_get_rate(priv->clk);
	if (!rate)
		return -ENODEV;
```

Ah, right. If there's no clock provided in the fake device, `devm_clk_get` will fail. In a vanilla x86 QEMU/GCE VM, there are *no* Renesas clocks. So, the `devm_clk_get` call will return `-ENOENT` or something similar, and the probe will fail. That means this driver is inaccessible in our virtualized environments.

I need to confirm this: Can `devm_clk_get` *ever* succeed with a fake device? If we use `CONFIG_COMPILE_TEST`, it *could* be compiled on x86, but at runtime, without a proper device tree providing the clock, it just *won't* probe. So, yep, this driver is definitely hardware-specific. It's not reachable.

Is there any way to mock the clock somehow? Syzkaller's `syz_gen_platform_device` doesn't mock clocks. It's just going to fail at that `devm_clk_get`.

Let's do a double-check, just in case... Nope. It's a standard SoC-specific driver.  I'm going to return `WorthFuzzing=false`. The reasoning is that it's a hardware-specific platform driver that requires specific clocks and MMIO resources that simply aren't available in virtualized environments like GCE or QEMU.

Just to be absolutely sure, let's quickly review the patch:

*   `Documentation/devicetree/bindings/ptp/renesas,rcar-gen4-gptp.yaml`
*   `MAINTAINERS`
*   `arch/arm64/boot/dts/renesas/r8a779g0.dtsi`
*   `drivers/ptp/Kconfig`
*   `drivers/ptp/Makefile`
*   `drivers/ptp/ptp_rcar_gen4.c`

All the changes are clearly Renesas R-Car Gen4 gPTP specific. Okay, decision confirmed. I'll set WorthFuzzing to false.



4/2 2026/07/22 09:04 tool set-results
0m Args:
{
  "EnableConfigs": [],
  "FocusSymbols": [],
  "Reasoning": "The patch introduces a hardware-specific platform driver for the Renesas R-Car Gen4 gPTP timer. The driver requires specific hardware resources, including MMIO regions and SoC-specific clocks, to successfully probe and execute. These resources are not available in generic virtualized environments like GCE or QEMU, making the code unreachable for fuzzing.",
  "WorthFuzzing": false
}

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch introduces a hardware-specific platform driver for the Renesas R-Car Gen4 gPTP timer. The driver requires specific hardware resources, including MMIO regions and SoC-specific clocks, to successfully probe and execute. These resources are not available in generic virtualized environments like GCE or QEMU, making the code unreachable for fuzzing.",
  "WorthFuzzing": false
}

LLM Calls Summary:
Total Calls Total Tokens Avg Tokens Total Duration (Seconds) Avg Duration (Seconds)
Tool Calls Summary:
Total Calls Total Duration (Seconds) Avg Duration (Seconds)