Devicetree
 help / color / mirror / Atom feed
* [PATCH 1/2] dt-bindings: devfreq: Document support for Airoha Subsystem devfreq
@ 2026-08-10 14:30 Christian Marangi
  2026-08-10 14:30 ` [PATCH 2/2] PM / devfreq: add Airoha SoC devfreq driver Christian Marangi
  2026-08-10 14:39 ` [PATCH 1/2] dt-bindings: devfreq: Document support for Airoha Subsystem devfreq sashiko-bot
  0 siblings, 2 replies; 4+ messages in thread
From: Christian Marangi @ 2026-08-10 14:30 UTC (permalink / raw)
  To: MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Christian Marangi, linux-pm,
	devicetree, linux-kernel

Airoha SoC contains multiple subsystem that are scaled to a
specific OPP taking the CPU clock as reference. Such sybsystem
can enter idle or performance state based on the system load
and power consumption conditions.

Example of such subsystem are GSW (Gigabit Switch), NPU (Custom
Risc Co-Processor for Network acceleration), SOE (Crypto Module) BUS...

Document all the required property and provide examples for the various
subsystem OPP + devfreq nodes.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
 .../bindings/devfreq/airoha,devfreq.yaml      | 114 ++++++++++++++++++
 1 file changed, 114 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/devfreq/airoha,devfreq.yaml

diff --git a/Documentation/devicetree/bindings/devfreq/airoha,devfreq.yaml b/Documentation/devicetree/bindings/devfreq/airoha,devfreq.yaml
new file mode 100644
index 000000000000..2f84486cb209
--- /dev/null
+++ b/Documentation/devicetree/bindings/devfreq/airoha,devfreq.yaml
@@ -0,0 +1,114 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/devfreq/airoha,devfreq.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Airoha SoC Subsystem Devfreq
+
+maintainers:
+  - Christian Marangi <ansuelsmth@gmail.com>
+
+description:
+  Airoha SoC contains multiple subsystem that are scaled to a
+  specific OPP taking the CPU clock as reference. Such sybsystem
+  can enter idle or performance state based on the system load
+  and power consumption conditions.
+
+  Example of such subsystem are GSW (Gigabit Switch), NPU (Custom
+  Risc Co-Processor for Network acceleration), SOE (Crypto Module) BUS...
+
+properties:
+  compatible:
+    const: airoha,devfreq
+
+  clocks:
+    maxItems: 1
+
+  operating-points-v2:
+    description:
+      OPP table of the related subsystem supported rates that referenced
+      clocks will be scaled to.
+
+required:
+  - compatible
+  - clocks
+  - operating-points-v2
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/en7523-clk.h>
+
+    npu_opp_table: opp-table-npu {
+        compatible = "operating-points-v2";
+
+        npu_low: opp-400000000 {
+           opp-hz = /bits/ 64 <400000000>;
+        };
+
+        npu_high: opp-720000000 {
+           opp-hz = /bits/ 64 <720000000>;
+        };
+    };
+
+    emi_opp_table: opp-table-emi {
+        compatible = "operating-points-v2";
+
+        emi_low: opp-400000000 {
+            opp-hz = /bits/ 64 <400000000>;
+        };
+
+        emi_high: opp-540000000 {
+           opp-hz = /bits/ 64 <540000000>;
+        };
+    };
+
+    bus_opp_table: opp-table-bus {
+        compatible = "operating-points-v2";
+
+        bus_low: opp-200000000 {
+           opp-hz = /bits/ 64 <200000000>;
+        };
+
+        bus_high: opp-300000000 {
+           opp-hz = /bits/ 64 <300000000>;
+        };
+    };
+
+    gsw_opp_table: opp-table-gsw {
+        compatible = "operating-points-v2";
+
+        gsw_low: opp-200000000 {
+            opp-hz = /bits/ 64 <200000000>;
+        };
+
+        gsw_high: opp-500000000 {
+           opp-hz = /bits/ 64 <500000000>;
+        };
+    };
+
+    npu-devfreq {
+        compatible = "airoha,devfreq";
+        operating-points-v2 = <&npu_opp_table>;
+        clocks = <&scuclk EN7523_CLK_NPU>;
+    };
+
+    emi-devfreq {
+        compatible = "airoha,devfreq";
+        operating-points-v2 = <&emi_opp_table>;
+        clocks = <&scuclk EN7523_CLK_EMI>;
+    };
+
+    bus-devfreq {
+        compatible = "airoha,devfreq";
+        operating-points-v2 = <&bus_opp_table>;
+        clocks = <&scuclk EN7523_CLK_BUS>;
+    };
+
+    gsw-devfreq {
+        compatible = "airoha,devfreq";
+        operating-points-v2 = <&gsw_opp_table>;
+        clocks = <&scuclk EN7523_CLK_GSW>;
+    };
-- 
2.53.0


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

* [PATCH 2/2] PM / devfreq: add Airoha SoC devfreq driver
  2026-08-10 14:30 [PATCH 1/2] dt-bindings: devfreq: Document support for Airoha Subsystem devfreq Christian Marangi
@ 2026-08-10 14:30 ` Christian Marangi
  2026-08-10 14:57   ` sashiko-bot
  2026-08-10 14:39 ` [PATCH 1/2] dt-bindings: devfreq: Document support for Airoha Subsystem devfreq sashiko-bot
  1 sibling, 1 reply; 4+ messages in thread
From: Christian Marangi @ 2026-08-10 14:30 UTC (permalink / raw)
  To: MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Christian Marangi, linux-pm,
	devicetree, linux-kernel

Add simple Airoha SoC devfreq driver. This simple driver register a
driver from a given clock and register a passive governor to scale the
frequency with the CPU frequency.

required-opp on the CPU frequency will be used to correctly bind the
clock to the related CPU frequency.

GSW, NPU, SOE, BUS and many other clock will register this devfreq
driver to scale all these internal peripheral  from idle to performance
mode.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
 drivers/devfreq/Kconfig          | 10 ++++
 drivers/devfreq/Makefile         |  1 +
 drivers/devfreq/airoha-devfreq.c | 99 ++++++++++++++++++++++++++++++++
 3 files changed, 110 insertions(+)
 create mode 100644 drivers/devfreq/airoha-devfreq.c

diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index c999c4a1e567..1e857a7e9caf 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -75,6 +75,16 @@ config DEVFREQ_GOV_PASSIVE
 
 comment "DEVFREQ Drivers"
 
+config ARM_AIROHA_DEVFREQ
+	tristate "Scaling support for Airoha SoC"
+	depends on ARCH_AIROHA || COMPILE_TEST
+	select DEVFREQ_GOV_PASSIVE
+	help
+	  This adds the DEVFREQ driver for the Airoha SoC.
+
+	  The driver register with the cpufreq notifier and find the right frequency
+	  based on the required OPP set in DT.
+
 config ARM_EXYNOS_BUS_DEVFREQ
 	tristate "ARM Exynos Generic Memory Bus DEVFREQ Driver"
 	depends on ARCH_EXYNOS || COMPILE_TEST
diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
index 404179d79a9d..5ca27684dee3 100644
--- a/drivers/devfreq/Makefile
+++ b/drivers/devfreq/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_DEVFREQ_GOV_USERSPACE)	+= governor_userspace.o
 obj-$(CONFIG_DEVFREQ_GOV_PASSIVE)	+= governor_passive.o
 
 # DEVFREQ Drivers
+obj-$(CONFIG_ARM_AIROHA_DEVFREQ)	+= airoha-devfreq.o
 obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ)	+= exynos-bus.o
 obj-$(CONFIG_ARM_HISI_UNCORE_DEVFREQ)	+= hisi_uncore_freq.o
 obj-$(CONFIG_ARM_IMX_BUS_DEVFREQ)	+= imx-bus.o
diff --git a/drivers/devfreq/airoha-devfreq.c b/drivers/devfreq/airoha-devfreq.c
new file mode 100644
index 000000000000..cb6d8b49e4a4
--- /dev/null
+++ b/drivers/devfreq/airoha-devfreq.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/cpufreq.h>
+#include <linux/devfreq.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/slab.h>
+#include <linux/pm_opp.h>
+
+struct airoha_devfreq_data {
+	struct clk *clk;
+
+	struct devfreq_passive_data gov_data;
+};
+
+static int airoha_devfreq_get_cur_freq(struct device *dev, unsigned long *freq)
+{
+	struct airoha_devfreq_data *data = dev_get_drvdata(dev);
+
+	*freq = clk_get_rate(data->clk);
+
+	return 0;
+};
+
+static int airoha_devfreq_target(struct device *dev, unsigned long *freq,
+				 u32 flags)
+{
+	struct airoha_devfreq_data *data = dev_get_drvdata(dev);
+
+	return clk_set_rate(data->clk, *freq);
+};
+
+static int airoha_devfreq_get_dev_status(struct device *dev,
+					 struct devfreq_dev_status *stat)
+{
+	struct airoha_devfreq_data *data = dev_get_drvdata(dev);
+
+	stat->busy_time = 0;
+	stat->total_time = 0;
+	stat->current_frequency = clk_get_rate(data->clk);
+
+	return 0;
+};
+
+static struct devfreq_dev_profile airoha_devfreq_devfreq_profile = {
+	.target = airoha_devfreq_target,
+	.get_dev_status = airoha_devfreq_get_dev_status,
+	.get_cur_freq = airoha_devfreq_get_cur_freq
+};
+
+static int airoha_devfreq_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct airoha_devfreq_data *data;
+	struct devfreq *devfreq;
+	int ret;
+
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->clk = devm_clk_get_enabled(dev, NULL);
+	if (IS_ERR(data->clk))
+		return dev_err_probe(dev, PTR_ERR(data->clk), "failed to get clk\n");
+
+	ret = devm_pm_opp_of_add_table(dev);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to parse fab freq thresholds\n");
+
+	dev_set_drvdata(dev, data);
+
+	data->gov_data.parent_type = CPUFREQ_PARENT_DEV;
+	devfreq = devm_devfreq_add_device(dev, &airoha_devfreq_devfreq_profile,
+					  DEVFREQ_GOV_PASSIVE, &data->gov_data);
+
+	return PTR_ERR_OR_ZERO(devfreq);
+};
+
+static const struct of_device_id airoha_devfreq_match_table[] = {
+	{ .compatible = "airoha,devfreq" },
+	{}
+};
+
+static struct platform_driver airoha_devfreq_driver = {
+	.probe		= airoha_devfreq_probe,
+	.driver		= {
+		.name   = "airoha-devfreq",
+		.of_match_table = airoha_devfreq_match_table,
+	},
+};
+module_platform_driver(airoha_devfreq_driver);
+
+MODULE_DESCRIPTION("Airoha Devfreq driver");
+MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
+MODULE_LICENSE("GPL");
-- 
2.53.0


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

* Re: [PATCH 1/2] dt-bindings: devfreq: Document support for Airoha Subsystem devfreq
  2026-08-10 14:30 [PATCH 1/2] dt-bindings: devfreq: Document support for Airoha Subsystem devfreq Christian Marangi
  2026-08-10 14:30 ` [PATCH 2/2] PM / devfreq: add Airoha SoC devfreq driver Christian Marangi
@ 2026-08-10 14:39 ` sashiko-bot
  1 sibling, 0 replies; 4+ messages in thread
From: sashiko-bot @ 2026-08-10 14:39 UTC (permalink / raw)
  To: Christian Marangi; +Cc: conor+dt, robh, devicetree

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [Medium] The compatible string `airoha,devfreq` is overly generic and lacks an SoC-specific identifier.
- [Medium] The binding introduces purely virtual nodes with OS-specific names (`*-devfreq`) instead of describing the actual hardware topology.
- [Low] Typos and grammatical errors in the binding description.
--

--- Patch [1]: [PATCH 1/2] dt-bindings: devfreq: Document support for Airoha Subsystem devfreq ---
commit 372abcdd0c5df2cbcf3b1b6f064f1949fb955f9d
Author: Christian Marangi <ansuelsmth@gmail.com>

dt-bindings: devfreq: Document support for Airoha Subsystem devfreq

This commit documents the devicetree bindings for Airoha SoC subsystems
that scale to specific operating performance points (OPP) based on CPU
clock reference.

> diff --git a/Documentation/devicetree/bindings/devfreq/airoha,devfreq.yaml b/Documentation/devicetree/bindings/devfreq/airoha,devfreq.yaml
> new file mode 100644
> index 0000000000000..2f84486cb2096
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/devfreq/airoha,devfreq.yaml
> @@ -0,0 +1,114 @@
[ ... ]
> +description:
> +  Airoha SoC contains multiple subsystem that are scaled to a
> +  specific OPP taking the CPU clock as reference. Such sybsystem
> +  can enter idle or performance state based on the system load
> +  and power consumption conditions.
> +
> +  Example of such subsystem are GSW (Gigabit Switch), NPU (Custom

[Severity: Low]
This isn't a bug, but there are a few typos in this description. Should
"multiple subsystem" and "Example of such subsystem" be plural? Also,
"sybsystem" appears to be misspelled.

> +  Risc Co-Processor for Network acceleration), SOE (Crypto Module) BUS...
> +
> +properties:
> +  compatible:
> +    const: airoha,devfreq

[Severity: Medium]
Will using a generic module string like airoha,devfreq prevent the OS from
distinguishing between hardware variants on future Airoha SoCs? Devicetree
best practices typically mandate SoC-specific compatible strings, such as
airoha,en7523-devfreq, to cleanly handle future hardware variations or quirks
without breaking the DT ABI.

[ ... ]
> +examples:
> +  - |
> +    #include <dt-bindings/clock/en7523-clk.h>
[ ... ]
> +    npu-devfreq {
> +        compatible = "airoha,devfreq";
> +        operating-points-v2 = <&npu_opp_table>;
> +        clocks = <&scuclk EN7523_CLK_NPU>;
> +    };
> +
> +    emi-devfreq {
> +        compatible = "airoha,devfreq";
> +        operating-points-v2 = <&emi_opp_table>;
> +        clocks = <&scuclk EN7523_CLK_EMI>;
> +    };

[Severity: Medium]
Do these example nodes describe Linux driver frameworks rather than the actual
hardware topology? 

Since devicetree is meant to describe hardware, it appears these virtual nodes
lack hardware resources like reg properties and use Linux subsystem terminology
(devfreq) in their names purely to bind a Linux driver. Should the clocks and
OPP tables be defined directly within the hardware device nodes they scale,
such as the NPU, EMI, or GSW nodes?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260810143057.651478-1-ansuelsmth@gmail.com?part=1

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

* Re: [PATCH 2/2] PM / devfreq: add Airoha SoC devfreq driver
  2026-08-10 14:30 ` [PATCH 2/2] PM / devfreq: add Airoha SoC devfreq driver Christian Marangi
@ 2026-08-10 14:57   ` sashiko-bot
  0 siblings, 0 replies; 4+ messages in thread
From: sashiko-bot @ 2026-08-10 14:57 UTC (permalink / raw)
  To: Christian Marangi; +Cc: devicetree, conor+dt, robh

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [Medium] The driver is missing the `MODULE_DEVICE_TABLE(of, ...)` macro for its OF match table, preventing automatic module loading.
- [Medium] The `airoha_devfreq_target` callback fails to resolve the requested frequency to a valid OPP and does not update `*freq` with the actual applied frequency.
- [Low] Multiple function definitions end with an illegal trailing semicolon.
--

--- Patch [2]: [PATCH 2/2] PM / devfreq: add Airoha SoC devfreq driver ---
commit 541990b8210ffb6d5026b9bcd5630443b99f63ec
Author: Christian Marangi <ansuelsmth@gmail.com>

PM / devfreq: add Airoha SoC devfreq driver

This commit adds a simple Airoha SoC devfreq driver. It registers a
passive governor to scale various internal peripheral clocks based on
the CPU frequency requirements.

> diff --git a/drivers/devfreq/airoha-devfreq.c b/drivers/devfreq/airoha-devfreq.c
> new file mode 100644
> index 0000000000000..cb6d8b49e4a40
> --- /dev/null
> +++ b/drivers/devfreq/airoha-devfreq.c

[ ... ]

> +static int airoha_devfreq_get_cur_freq(struct device *dev, unsigned long *freq)
> +{
> +	struct airoha_devfreq_data *data = dev_get_drvdata(dev);
> +
> +	*freq = clk_get_rate(data->clk);
> +
> +	return 0;
> +};

[Severity: Low]
This isn't a bug, but should this function definition end with a semicolon?

> +
> +static int airoha_devfreq_target(struct device *dev, unsigned long *freq,
> +				 u32 flags)
> +{
> +	struct airoha_devfreq_data *data = dev_get_drvdata(dev);
> +
> +	return clk_set_rate(data->clk, *freq);
> +};

[Severity: Medium]
Does this function need to resolve the requested frequency to a valid OPP
and update the freq pointer with the actual applied frequency?

If the governor or PM QoS requests a frequency that doesn't exactly match
an OPP, applying it directly without resolving (e.g., using
devfreq_recommended_opp) leaves the unrounded frequency in the freq pointer.

The devfreq core tracks frequency statistics using exact matches against
its freq_table.

Won't this cause devfreq_get_freq_level() lookups to fail
in devfreq_update_status(), resulting in spamming the kernel log with
'Couldn't update frequency transition information' warnings?

Also, similar to airoha_devfreq_get_cur_freq(), this function definition
has a trailing semicolon that can probably be removed.

[ ... ]

> +static int airoha_devfreq_probe(struct platform_device *pdev)
> +{

[ ... ]

> +	return PTR_ERR_OR_ZERO(devfreq);
> +};
> +
> +static const struct of_device_id airoha_devfreq_match_table[] = {
> +	{ .compatible = "airoha,devfreq" },
> +	{}
> +};

[Severity: Medium]
Is this missing a MODULE_DEVICE_TABLE(of, airoha_devfreq_match_table)
declaration?

Without it, the modpost tool won't extract the compatible strings to
modules.alias.

Will user-space module loaders be able to automatically load this driver
when the hardware node is detected during boot or hotplug?

> +
> +static struct platform_driver airoha_devfreq_driver = {
> +	.probe		= airoha_devfreq_probe,
> +	.driver		= {
> +		.name   = "airoha-devfreq",
> +		.of_match_table = airoha_devfreq_match_table,
> +	},
> +};

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260810143057.651478-1-ansuelsmth@gmail.com?part=2

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

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

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-10 14:30 [PATCH 1/2] dt-bindings: devfreq: Document support for Airoha Subsystem devfreq Christian Marangi
2026-08-10 14:30 ` [PATCH 2/2] PM / devfreq: add Airoha SoC devfreq driver Christian Marangi
2026-08-10 14:57   ` sashiko-bot
2026-08-10 14:39 ` [PATCH 1/2] dt-bindings: devfreq: Document support for Airoha Subsystem devfreq sashiko-bot

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