Linux Power Management development
 help / color / mirror / Atom feed
* [PATCH v1 03/14] thermal/core: Make thermal_cooling_device_init_complete() non static
From: Daniel Lezcano @ 2026-04-19 18:21 UTC (permalink / raw)
  To: rafael
  Cc: gaurav.kohli, Zhang Rui, Lukasz Luba, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Lucas Stach, Russell King,
	Christian Gmeiner, David Airlie, Simona Vetter, Guenter Roeck,
	Joel Stanley, Andrew Jeffery, Thomas Weißschuh, Benson Leung,
	Pali Rohár, Avi Fishman, Tomer Maimon, Tali Perry,
	Patrick Venture, Nancy Yuen, Benjamin Fair, Heiko Stuebner,
	Thierry Reding, Jonathan Hunter, Bjorn Andersson, Konrad Dybcio,
	Amit Daniel Kachhap, Viresh Kumar, Neil Armstrong, Amit Kucheria,
	linux-pm, linux-kernel, linux-hwmon, Daniel Lezcano
In-Reply-To: <20260419182203.4083985-1-daniel.lezcano@oss.qualcomm.com>

In the process of separating clearly the OF code and the thermal core
code, let's split and export the
thermal_cooling_device_init_complete() function so it can be used by
an implementation inside the thermal OF code.

Signed-off-by: Daniel Lezcano <daniel.lezcano@oss.qualcomm.com>
---
 drivers/thermal/thermal_core.c | 12 ++++++++----
 drivers/thermal/thermal_core.h |  2 ++
 drivers/thermal/thermal_of.c   | 10 +++++++++-
 3 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 8a70768b46dd..35cf170f3fa1 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -1028,7 +1028,7 @@ static void thermal_zone_cdev_bind(struct thermal_zone_device *tz,
 		__thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
 }
 
-static void thermal_cooling_device_init_complete(struct thermal_cooling_device *cdev)
+void thermal_cooling_device_init_complete(struct thermal_cooling_device *cdev)
 {
 	struct thermal_zone_device *tz;
 
@@ -1127,8 +1127,6 @@ __thermal_cooling_device_register(struct device_node *np,
 	if (current_state <= cdev->max_state)
 		thermal_debug_cdev_add(cdev, current_state);
 
-	thermal_cooling_device_init_complete(cdev);
-
 	return cdev;
 
 out_cooling_dev:
@@ -1159,7 +1157,13 @@ struct thermal_cooling_device *
 thermal_cooling_device_register(const char *type, void *devdata,
 				const struct thermal_cooling_device_ops *ops)
 {
-	return __thermal_cooling_device_register(NULL, type, devdata, ops);
+	struct thermal_cooling_device *cdev;
+
+	cdev = __thermal_cooling_device_register(NULL, type, devdata, ops);
+	if (!IS_ERR(cdev))
+		thermal_cooling_device_init_complete(cdev);
+
+	return cdev;
 }
 EXPORT_SYMBOL_GPL(thermal_cooling_device_register);
 
diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h
index bdd59947b24f..6e44bcf37b00 100644
--- a/drivers/thermal/thermal_core.h
+++ b/drivers/thermal/thermal_core.h
@@ -269,6 +269,8 @@ void thermal_zone_device_critical_shutdown(struct thermal_zone_device *tz);
 void thermal_governor_update_tz(struct thermal_zone_device *tz,
 				enum thermal_notify_event reason);
 
+void thermal_cooling_device_init_complete(struct thermal_cooling_device *cdev);
+
 struct thermal_cooling_device *
 __thermal_cooling_device_register(struct device_node *np,
 				  const char *type, void *devdata,
diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c
index 398157e740fc..35d542aac7f8 100644
--- a/drivers/thermal/thermal_of.c
+++ b/drivers/thermal/thermal_of.c
@@ -531,7 +531,15 @@ thermal_of_cooling_device_register(struct device_node *np,
 				   const char *type, void *devdata,
 				   const struct thermal_cooling_device_ops *ops)
 {
-	return __thermal_cooling_device_register(np, type, devdata, ops);
+	struct thermal_cooling_device *cdev;
+
+	cdev = __thermal_cooling_device_register(np, type, devdata, ops);
+	if (IS_ERR(cdev))
+		return cdev;
+
+	thermal_cooling_device_init_complete(cdev);
+
+	return cdev;
 }
 EXPORT_SYMBOL_GPL(thermal_of_cooling_device_register);
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH v1 04/14] thermal/of: Move the node pointer assignation in the OF code file
From: Daniel Lezcano @ 2026-04-19 18:21 UTC (permalink / raw)
  To: rafael
  Cc: gaurav.kohli, Zhang Rui, Lukasz Luba, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Lucas Stach, Russell King,
	Christian Gmeiner, David Airlie, Simona Vetter, Guenter Roeck,
	Joel Stanley, Andrew Jeffery, Thomas Weißschuh, Benson Leung,
	Pali Rohár, Avi Fishman, Tomer Maimon, Tali Perry,
	Patrick Venture, Nancy Yuen, Benjamin Fair, Heiko Stuebner,
	Thierry Reding, Jonathan Hunter, Bjorn Andersson, Konrad Dybcio,
	Amit Daniel Kachhap, Viresh Kumar, Neil Armstrong, Amit Kucheria,
	linux-pm, linux-kernel, linux-hwmon, Daniel Lezcano
In-Reply-To: <20260419182203.4083985-1-daniel.lezcano@oss.qualcomm.com>

The node pointer being assigned to the cooling device structure is an
action done by the thermal OF only and does not belong to the core
framework code. Move the node pointer assignation in the thermal OF
code. Consequently, the devm_thermal_of_cooling_device_register() can
call its non-devm version resulting in a more intuitive design of the
API.

Signed-off-by: Daniel Lezcano <daniel.lezcano@oss.qualcomm.com>
---
 drivers/thermal/thermal_core.c | 1 -
 drivers/thermal/thermal_of.c   | 3 ++-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 35cf170f3fa1..26231acea382 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -1089,7 +1089,6 @@ __thermal_cooling_device_register(struct device_node *np,
 
 	mutex_init(&cdev->lock);
 	INIT_LIST_HEAD(&cdev->thermal_instances);
-	cdev->np = np;
 	cdev->ops = ops;
 	cdev->updated = false;
 	cdev->device.class = &thermal_class;
diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c
index 35d542aac7f8..85fc78bc9e73 100644
--- a/drivers/thermal/thermal_of.c
+++ b/drivers/thermal/thermal_of.c
@@ -537,6 +537,7 @@ thermal_of_cooling_device_register(struct device_node *np,
 	if (IS_ERR(cdev))
 		return cdev;
 
+	cdev->np = np;
 	thermal_cooling_device_init_complete(cdev);
 
 	return cdev;
@@ -578,7 +579,7 @@ devm_thermal_of_cooling_device_register(struct device *dev,
 	if (!ptr)
 		return ERR_PTR(-ENOMEM);
 
-	tcd = __thermal_cooling_device_register(np, type, devdata, ops);
+	tcd = thermal_of_cooling_device_register(np, type, devdata, ops);
 	if (IS_ERR(tcd)) {
 		devres_free(ptr);
 		return tcd;
-- 
2.43.0


^ permalink raw reply related

* [PATCH v1 05/14] thermal/core: Remove node pointer parameter parameter when registering a tz
From: Daniel Lezcano @ 2026-04-19 18:21 UTC (permalink / raw)
  To: rafael
  Cc: gaurav.kohli, Zhang Rui, Lukasz Luba, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Lucas Stach, Russell King,
	Christian Gmeiner, David Airlie, Simona Vetter, Guenter Roeck,
	Joel Stanley, Andrew Jeffery, Thomas Weißschuh, Benson Leung,
	Pali Rohár, Avi Fishman, Tomer Maimon, Tali Perry,
	Patrick Venture, Nancy Yuen, Benjamin Fair, Heiko Stuebner,
	Thierry Reding, Jonathan Hunter, Bjorn Andersson, Konrad Dybcio,
	Amit Daniel Kachhap, Viresh Kumar, Neil Armstrong, Amit Kucheria,
	linux-pm, linux-kernel, linux-hwmon, Daniel Lezcano
In-Reply-To: <20260419182203.4083985-1-daniel.lezcano@oss.qualcomm.com>

Now we have a OF version for all functions registering a thermal zone
or a cooling device. Let's remove the device_node pointer parameter in
the core function which is inconsistent with non-OF code.

Signed-off-by: Daniel Lezcano <daniel.lezcano@oss.qualcomm.com>
---
 drivers/thermal/thermal_core.c | 6 ++----
 drivers/thermal/thermal_core.h | 3 +--
 drivers/thermal/thermal_of.c   | 2 +-
 3 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 26231acea382..2f5d214d51a1 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -1042,7 +1042,6 @@ void thermal_cooling_device_init_complete(struct thermal_cooling_device *cdev)
 
 /**
  * __thermal_cooling_device_register() - register a new thermal cooling device
- * @np:		a pointer to a device tree node.
  * @type:	the thermal cooling device type.
  * @devdata:	device private data.
  * @ops:	standard thermal cooling devices callbacks.
@@ -1057,8 +1056,7 @@ void thermal_cooling_device_init_complete(struct thermal_cooling_device *cdev)
  * ERR_PTR. Caller must check return value with IS_ERR*() helpers.
  */
 struct thermal_cooling_device *
-__thermal_cooling_device_register(struct device_node *np,
-				  const char *type, void *devdata,
+__thermal_cooling_device_register(const char *type, void *devdata,
 				  const struct thermal_cooling_device_ops *ops)
 {
 	struct thermal_cooling_device *cdev;
@@ -1158,7 +1156,7 @@ thermal_cooling_device_register(const char *type, void *devdata,
 {
 	struct thermal_cooling_device *cdev;
 
-	cdev = __thermal_cooling_device_register(NULL, type, devdata, ops);
+	cdev = __thermal_cooling_device_register(type, devdata, ops);
 	if (!IS_ERR(cdev))
 		thermal_cooling_device_init_complete(cdev);
 
diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h
index 6e44bcf37b00..d45455bb9e9e 100644
--- a/drivers/thermal/thermal_core.h
+++ b/drivers/thermal/thermal_core.h
@@ -272,8 +272,7 @@ void thermal_governor_update_tz(struct thermal_zone_device *tz,
 void thermal_cooling_device_init_complete(struct thermal_cooling_device *cdev);
 
 struct thermal_cooling_device *
-__thermal_cooling_device_register(struct device_node *np,
-				  const char *type, void *devdata,
+__thermal_cooling_device_register(const char *type, void *devdata,
 				  const struct thermal_cooling_device_ops *ops);
 
 /* Helpers */
diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c
index 85fc78bc9e73..3d2fb8f37b9c 100644
--- a/drivers/thermal/thermal_of.c
+++ b/drivers/thermal/thermal_of.c
@@ -533,7 +533,7 @@ thermal_of_cooling_device_register(struct device_node *np,
 {
 	struct thermal_cooling_device *cdev;
 
-	cdev = __thermal_cooling_device_register(np, type, devdata, ops);
+	cdev = __thermal_cooling_device_register(type, devdata, ops);
 	if (IS_ERR(cdev))
 		return cdev;
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH v1 06/14] thermal/core: Register cooling device non-OF drivers
From: Daniel Lezcano @ 2026-04-19 18:21 UTC (permalink / raw)
  To: rafael
  Cc: gaurav.kohli, Zhang Rui, Lukasz Luba, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Lucas Stach, Russell King,
	Christian Gmeiner, David Airlie, Simona Vetter, Guenter Roeck,
	Joel Stanley, Andrew Jeffery, Thomas Weißschuh, Benson Leung,
	Pali Rohár, Avi Fishman, Tomer Maimon, Tali Perry,
	Patrick Venture, Nancy Yuen, Benjamin Fair, Heiko Stuebner,
	Thierry Reding, Jonathan Hunter, Bjorn Andersson, Konrad Dybcio,
	Amit Daniel Kachhap, Viresh Kumar, Neil Armstrong, Amit Kucheria,
	linux-pm, linux-kernel, linux-hwmon, Daniel Lezcano
In-Reply-To: <20260419182203.4083985-1-daniel.lezcano@oss.qualcomm.com>

Provide a non-OF functions to register a cooling device in order to
have a clear separation between OF and non-OF code. Drivers not using
a devicetree can then migrate to this function.

Signed-off-by: Daniel Lezcano <daniel.lezcano@oss.qualcomm.com>
---
 drivers/thermal/thermal_core.c | 44 ++++++++++++++++++++++++++++++++++
 include/linux/thermal.h        | 13 ++++++++++
 2 files changed, 57 insertions(+)

diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 2f5d214d51a1..356a49e541fd 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -1164,6 +1164,50 @@ thermal_cooling_device_register(const char *type, void *devdata,
 }
 EXPORT_SYMBOL_GPL(thermal_cooling_device_register);
 
+static void thermal_cooling_device_release(struct device *dev, void *res)
+{
+	thermal_cooling_device_unregister(*(struct thermal_cooling_device **)res);
+}
+
+/**
+ * devm_thermal_cooling_device_register() - register a thermal cooling device
+ * @dev:	a valid struct device pointer of a sensor device.
+ * @type:	the thermal cooling device type.
+ * @devdata:	device private data.
+ * @ops:	standard thermal cooling devices callbacks.
+ *
+ * This function will register a cooling device with device tree node reference.
+ * This interface function adds a new thermal cooling device (fan/processor/...)
+ * to /sys/class/thermal/ folder as cooling_device[0-*]. It tries to bind itself
+ * to all the thermal zone devices registered at the same time.
+ *
+ * Return: a pointer to the created struct thermal_cooling_device or an
+ * ERR_PTR. Caller must check return value with IS_ERR*() helpers.
+ */
+struct thermal_cooling_device *
+devm_thermal_cooling_device_register(struct device *dev, const char *type,
+				     void *devdata, const struct thermal_cooling_device_ops *ops)
+{
+	struct thermal_cooling_device **ptr, *tcd;
+
+	ptr = devres_alloc(thermal_cooling_device_release, sizeof(*ptr),
+			   GFP_KERNEL);
+	if (!ptr)
+		return ERR_PTR(-ENOMEM);
+
+	tcd = thermal_cooling_device_register(type, devdata, ops);
+	if (IS_ERR(tcd)) {
+		devres_free(ptr);
+		return tcd;
+	}
+
+	*ptr = tcd;
+	devres_add(dev, ptr);
+
+	return tcd;
+}
+EXPORT_SYMBOL_GPL(devm_thermal_cooling_device_register);
+
 static bool thermal_cooling_device_present(struct thermal_cooling_device *cdev)
 {
 	struct thermal_cooling_device *pos = NULL;
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 0ddc77aeeca2..d9332b037188 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -260,6 +260,11 @@ devm_thermal_of_cooling_device_register(struct device *dev,
 				struct device_node *np,
 				const char *type, void *devdata,
 				const struct thermal_cooling_device_ops *ops);
+
+struct thermal_cooling_device *
+devm_thermal_cooling_device_register(struct device *dev, const char *type,
+				     void *devdata, const struct thermal_cooling_device_ops *ops);
+
 void thermal_cooling_device_update(struct thermal_cooling_device *);
 void thermal_cooling_device_unregister(struct thermal_cooling_device *);
 struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name);
@@ -317,6 +322,14 @@ devm_thermal_of_cooling_device_register(struct device *dev,
 {
 	return ERR_PTR(-ENODEV);
 }
+
+struct thermal_cooling_device *
+devm_thermal_cooling_device_register(struct device *dev, const char *type,
+				     void *devdata, const struct thermal_cooling_device_ops *ops)
+{
+	return ERR_PTR(-ENODEV);
+}
+
 static inline void thermal_cooling_device_unregister(
 	struct thermal_cooling_device *cdev)
 { }
-- 
2.43.0


^ permalink raw reply related

* [PATCH v1 07/14] hwmon:: Use non-OF thermal cooling device register function
From: Daniel Lezcano @ 2026-04-19 18:21 UTC (permalink / raw)
  To: rafael
  Cc: gaurav.kohli, Zhang Rui, Lukasz Luba, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Lucas Stach, Russell King,
	Christian Gmeiner, David Airlie, Simona Vetter, Guenter Roeck,
	Joel Stanley, Andrew Jeffery, Thomas Weißschuh, Benson Leung,
	Pali Rohár, Avi Fishman, Tomer Maimon, Tali Perry,
	Patrick Venture, Nancy Yuen, Benjamin Fair, Heiko Stuebner,
	Thierry Reding, Jonathan Hunter, Bjorn Andersson, Konrad Dybcio,
	Amit Daniel Kachhap, Viresh Kumar, Neil Armstrong, Amit Kucheria,
	linux-pm, linux-kernel, linux-hwmon,
	open list:CHROMEOS EC HARDWARE MONITORING
In-Reply-To: <20260419182203.4083985-1-daniel.lezcano@oss.qualcomm.com>

Make HWMON drivers which are not based on device tree to use the
corresponding non-OF functions.

Signed-off-by: Daniel Lezcano <daniel.lezcano@oss.qualcomm.com>
---
 drivers/hwmon/cros_ec_hwmon.c  | 4 ++--
 drivers/hwmon/dell-smm-hwmon.c | 4 ++--
 drivers/hwmon/mlxreg-fan.c     | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/hwmon/cros_ec_hwmon.c b/drivers/hwmon/cros_ec_hwmon.c
index 6cf5ab0f4b73..77dd9f28962d 100644
--- a/drivers/hwmon/cros_ec_hwmon.c
+++ b/drivers/hwmon/cros_ec_hwmon.c
@@ -532,8 +532,8 @@ static void cros_ec_hwmon_register_fan_cooling_devices(struct device *dev,
 
 		cpriv->hwmon_priv = priv;
 		cpriv->index = i;
-		cdev = devm_thermal_of_cooling_device_register(dev, NULL, type, cpriv,
-							       &cros_ec_thermal_cooling_ops);
+		cdev = devm_thermal_cooling_device_register(dev, type, cpriv,
+							    &cros_ec_thermal_cooling_ops);
 		if (IS_ERR(cdev)) {
 			dev_warn(dev, "failed to register fan %zu as a cooling device: %pe\n", i,
 				 cdev);
diff --git a/drivers/hwmon/dell-smm-hwmon.c b/drivers/hwmon/dell-smm-hwmon.c
index 038edffc1ac7..47b373ea6db4 100644
--- a/drivers/hwmon/dell-smm-hwmon.c
+++ b/drivers/hwmon/dell-smm-hwmon.c
@@ -1161,8 +1161,8 @@ static int dell_smm_init_cdev(struct device *dev, u8 fan_num)
 	if (cdata) {
 		cdata->fan_num = fan_num;
 		cdata->data = data;
-		cdev = devm_thermal_of_cooling_device_register(dev, NULL, name, cdata,
-							       &dell_smm_cooling_ops);
+		cdev = devm_thermal_cooling_device_register(dev, name, cdata,
+							    &dell_smm_cooling_ops);
 		if (IS_ERR(cdev)) {
 			devm_kfree(dev, cdata);
 			ret = PTR_ERR(cdev);
diff --git a/drivers/hwmon/mlxreg-fan.c b/drivers/hwmon/mlxreg-fan.c
index 137a90dd2075..860de6cfd8a4 100644
--- a/drivers/hwmon/mlxreg-fan.c
+++ b/drivers/hwmon/mlxreg-fan.c
@@ -583,8 +583,8 @@ static int mlxreg_fan_cooling_config(struct device *dev, struct mlxreg_fan *fan)
 		pwm->fan = fan;
 		/* Set minimal PWM speed. */
 		pwm->last_hwmon_state = MLXREG_FAN_PWM_DUTY2STATE(MLXREG_FAN_MIN_DUTY);
-		pwm->cdev = devm_thermal_of_cooling_device_register(dev, NULL, mlxreg_fan_name[i],
-								    pwm, &mlxreg_fan_cooling_ops);
+		pwm->cdev = devm_thermal_cooling_device_register(dev, mlxreg_fan_name[i],
+								 pwm, &mlxreg_fan_cooling_ops);
 		if (IS_ERR(pwm->cdev)) {
 			dev_err(dev, "Failed to register cooling device\n");
 			return PTR_ERR(pwm->cdev);
-- 
2.43.0


^ permalink raw reply related

* [PATCH v1 08/14] thermal/core: Move OF functions def in the CONFIG_OF section in thermal.h
From: Daniel Lezcano @ 2026-04-19 18:21 UTC (permalink / raw)
  To: rafael
  Cc: gaurav.kohli, Zhang Rui, Lukasz Luba, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Lucas Stach, Russell King,
	Christian Gmeiner, David Airlie, Simona Vetter, Guenter Roeck,
	Joel Stanley, Andrew Jeffery, Thomas Weißschuh, Benson Leung,
	Pali Rohár, Avi Fishman, Tomer Maimon, Tali Perry,
	Patrick Venture, Nancy Yuen, Benjamin Fair, Heiko Stuebner,
	Thierry Reding, Jonathan Hunter, Bjorn Andersson, Konrad Dybcio,
	Amit Daniel Kachhap, Viresh Kumar, Neil Armstrong, Amit Kucheria,
	linux-pm, linux-kernel, linux-hwmon, Daniel Lezcano
In-Reply-To: <20260419182203.4083985-1-daniel.lezcano@oss.qualcomm.com>

Now that OF functions are used only by OF drivers, let's move and
group the functions definitions under the CONFIG_OF block. There is no
need to keep them out because of non-OF drivers using them.

Signed-off-by: Daniel Lezcano <daniel.lezcano@oss.qualcomm.com>
---
 include/linux/thermal.h | 48 +++++++++++++++++++++++------------------
 1 file changed, 27 insertions(+), 21 deletions(-)

diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index d9332b037188..f7b8651c1ed0 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -198,6 +198,16 @@ struct thermal_zone_device *devm_thermal_of_zone_register(struct device *dev, in
 
 void devm_thermal_of_zone_unregister(struct device *dev, struct thermal_zone_device *tz);
 
+struct thermal_cooling_device *
+thermal_of_cooling_device_register(struct device_node *np,
+				   const char *type, void *data,
+				   const struct thermal_cooling_device_ops *ops);
+
+struct thermal_cooling_device *
+devm_thermal_of_cooling_device_register(struct device *dev,
+					struct device_node *np,
+					const char *type, void *devdata,
+					const struct thermal_cooling_device_ops *ops);
 #else
 
 static inline
@@ -211,6 +221,23 @@ static inline void devm_thermal_of_zone_unregister(struct device *dev,
 						   struct thermal_zone_device *tz)
 {
 }
+
+static inline struct thermal_cooling_device *
+thermal_of_cooling_device_register(struct device_node *np,
+				   const char *type, void *devdata,
+				   const struct thermal_cooling_device_ops *ops)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline struct thermal_cooling_device *
+devm_thermal_of_cooling_device_register(struct device *dev,
+					struct device_node *np,
+					const char *type, void *devdata,
+					const struct thermal_cooling_device_ops *ops)
+{
+	return ERR_PTR(-ENODEV);
+}
 #endif
 
 int for_each_thermal_trip(struct thermal_zone_device *tz,
@@ -252,14 +279,6 @@ void thermal_zone_device_update(struct thermal_zone_device *,
 
 struct thermal_cooling_device *thermal_cooling_device_register(const char *,
 		void *, const struct thermal_cooling_device_ops *);
-struct thermal_cooling_device *
-thermal_of_cooling_device_register(struct device_node *np, const char *, void *,
-				   const struct thermal_cooling_device_ops *);
-struct thermal_cooling_device *
-devm_thermal_of_cooling_device_register(struct device *dev,
-				struct device_node *np,
-				const char *type, void *devdata,
-				const struct thermal_cooling_device_ops *ops);
 
 struct thermal_cooling_device *
 devm_thermal_cooling_device_register(struct device *dev, const char *type,
@@ -309,19 +328,6 @@ static inline struct thermal_cooling_device *
 thermal_cooling_device_register(const char *type, void *devdata,
 	const struct thermal_cooling_device_ops *ops)
 { return ERR_PTR(-ENODEV); }
-static inline struct thermal_cooling_device *
-thermal_of_cooling_device_register(struct device_node *np,
-	const char *type, void *devdata,
-	const struct thermal_cooling_device_ops *ops)
-{ return ERR_PTR(-ENODEV); }
-static inline struct thermal_cooling_device *
-devm_thermal_of_cooling_device_register(struct device *dev,
-				struct device_node *np,
-				const char *type, void *devdata,
-				const struct thermal_cooling_device_ops *ops)
-{
-	return ERR_PTR(-ENODEV);
-}
 
 struct thermal_cooling_device *
 devm_thermal_cooling_device_register(struct device *dev, const char *type,
-- 
2.43.0


^ permalink raw reply related

* [PATCH v1 09/14] thermal/core: Put of_node field cooling device structure under Kconfig option
From: Daniel Lezcano @ 2026-04-19 18:21 UTC (permalink / raw)
  To: rafael
  Cc: gaurav.kohli, Zhang Rui, Lukasz Luba, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Lucas Stach, Russell King,
	Christian Gmeiner, David Airlie, Simona Vetter, Guenter Roeck,
	Joel Stanley, Andrew Jeffery, Thomas Weißschuh, Benson Leung,
	Pali Rohár, Avi Fishman, Tomer Maimon, Tali Perry,
	Patrick Venture, Nancy Yuen, Benjamin Fair, Heiko Stuebner,
	Thierry Reding, Jonathan Hunter, Bjorn Andersson, Konrad Dybcio,
	Amit Daniel Kachhap, Viresh Kumar, Neil Armstrong, Amit Kucheria,
	linux-pm, linux-kernel, linux-hwmon, Daniel Lezcano
In-Reply-To: <20260419182203.4083985-1-daniel.lezcano@oss.qualcomm.com>

The device node pointer in the cooling device structure is only needed
by the thermal OF in order to bind a thermal zone with a cooling
device. Now only the OF based drivers are using the thermal OF
functions and do not call the function with a NULL device_node
parameter as before. We can put this field under the CONFIG_THERMAL_OF
condition and make it go away if the device tree is not used.

Signed-off-by: Daniel Lezcano <daniel.lezcano@oss.qualcomm.com>
---
 include/linux/thermal.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index f7b8651c1ed0..a8e870ca2e27 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -125,7 +125,6 @@ struct thermal_cooling_device {
 	const char *type;
 	unsigned long max_state;
 	struct device device;
-	struct device_node *np;
 	void *devdata;
 	void *stats;
 	const struct thermal_cooling_device_ops *ops;
@@ -133,6 +132,9 @@ struct thermal_cooling_device {
 	struct mutex lock; /* protect thermal_instances list */
 	struct list_head thermal_instances;
 	struct list_head node;
+#ifdef CONFIG_THERMAL_OF
+	struct device_node *np;
+#endif
 #ifdef CONFIG_THERMAL_DEBUGFS
 	struct thermal_debugfs *debugfs;
 #endif
-- 
2.43.0


^ permalink raw reply related

* [PATCH v1 10/14] thermal/of: Rename the devm_thermal_of_cooling_device_register() function
From: Daniel Lezcano @ 2026-04-19 18:21 UTC (permalink / raw)
  To: rafael
  Cc: gaurav.kohli, Zhang Rui, Lukasz Luba, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Lucas Stach, Russell King,
	Christian Gmeiner, David Airlie, Simona Vetter, Guenter Roeck,
	Joel Stanley, Andrew Jeffery, Thomas Weißschuh, Benson Leung,
	Pali Rohár, Avi Fishman, Tomer Maimon, Tali Perry,
	Patrick Venture, Nancy Yuen, Benjamin Fair, Heiko Stuebner,
	Thierry Reding, Jonathan Hunter, Bjorn Andersson, Konrad Dybcio,
	Amit Daniel Kachhap, Viresh Kumar, Neil Armstrong, Amit Kucheria,
	linux-pm, linux-kernel, linux-hwmon, Krzysztof Kozlowski,
	Daniel Lezcano, Nathan Chancellor, Nick Desaulniers,
	Bill Wendling, Justin Stitt, Thomas Gleixner, Ingo Molnar,
	Jiri Slaby (SUSE), Mikko Perttunen, Svyatoslav Ryhel,
	moderated list:ARM/ASPEED MACHINE SUPPORT,
	moderated list:ARM/ASPEED MACHINE SUPPORT,
	moderated list:ARM/NUVOTON NPCM ARCHITECTURE,
	open list:TEGRA ARCHITECTURE SUPPORT,
	open list:ARM/QUALCOMM MAILING LIST,
	open list:KHADAS MCU MFD DRIVER,
	open list:CLANG/LLVM BUILD SUPPORT
In-Reply-To: <20260419182203.4083985-1-daniel.lezcano@oss.qualcomm.com>

The cooling devices can be composed with a cooling device controller
and a set of cooling devices attached to it. Until now, the DT
bindings were described using a node for the cooling device controller
and child nodes for all the cooling devices.

Recently, a new set of cooling devices were proposed with the same
bindings. Those were rejected because DT maintainers do not want this
format anymore. In place, a cooling device will be created with an
id. Whatever its meaning, the thermal OF will bind a thermal zone and
a cooling device by checking the device node pointer + the id are
matching the cooling map with the cooling device.

Actually this approach is consistent with the thermal which are also
registered with a device and an id.

In order to do a distinction between the old binding with child nodes
and the incoming new binding, let's rename the registering function
with a self-explanatory name.

Rename the functions:
	devm_thermal_of_cooling_device_register() -> devm_thermal_of_child_cooling_device_register()

Used the command:

     	 find . -type f -name '*.[ch]' -exec \
	 sed -i 's/devm_thermal_of_cooling_device_register/\
	 devm_thermal_of_child_cooling_device_register/g' {} \;

Did not used clang-format-diff because it does not indent correctly
and checkpatch complained. Manually reindented to make checkpatch
happy

Signed-off-by: Daniel Lezcano <daniel.lezcano@oss.qualcomm.com>
---
 drivers/hwmon/amc6821.c                  |  2 +-
 drivers/hwmon/aspeed-pwm-tacho.c         |  5 +++--
 drivers/hwmon/emc2305.c                  |  6 +++---
 drivers/hwmon/gpio-fan.c                 |  6 ++++--
 drivers/hwmon/max6650.c                  |  6 +++---
 drivers/hwmon/npcm750-pwm-fan.c          |  6 ++++--
 drivers/hwmon/pwm-fan.c                  |  5 +++--
 drivers/hwmon/qnap-mcu-hwmon.c           |  6 +++---
 drivers/hwmon/tc654.c                    |  5 +++--
 drivers/memory/tegra/tegra210-emc-core.c |  4 ++--
 drivers/soc/qcom/qcom_aoss.c             |  2 +-
 drivers/thermal/khadas_mcu_fan.c         |  7 ++++---
 drivers/thermal/tegra/soctherm.c         |  6 +++---
 drivers/thermal/thermal_of.c             | 12 ++++++------
 include/linux/thermal.h                  | 16 ++++++++--------
 15 files changed, 51 insertions(+), 43 deletions(-)

diff --git a/drivers/hwmon/amc6821.c b/drivers/hwmon/amc6821.c
index d5f864b360b0..8e5926b06070 100644
--- a/drivers/hwmon/amc6821.c
+++ b/drivers/hwmon/amc6821.c
@@ -1076,7 +1076,7 @@ static int amc6821_probe(struct i2c_client *client)
 				     "Failed to initialize hwmon\n");
 
 	if (IS_ENABLED(CONFIG_THERMAL) && fan_np && data->fan_cooling_levels)
-		return PTR_ERR_OR_ZERO(devm_thermal_of_cooling_device_register(dev,
+		return PTR_ERR_OR_ZERO(devm_thermal_of_child_cooling_device_register(dev,
 			fan_np, client->name, data, &amc6821_cooling_ops));
 
 	return 0;
diff --git a/drivers/hwmon/aspeed-pwm-tacho.c b/drivers/hwmon/aspeed-pwm-tacho.c
index aa159bf158a3..1c5945d4ba37 100644
--- a/drivers/hwmon/aspeed-pwm-tacho.c
+++ b/drivers/hwmon/aspeed-pwm-tacho.c
@@ -841,8 +841,9 @@ static int aspeed_create_pwm_cooling(struct device *dev,
 	}
 	snprintf(cdev->name, MAX_CDEV_NAME_LEN, "%pOFn%d", child, pwm_port);
 
-	cdev->tcdev = devm_thermal_of_cooling_device_register(dev, child,
-					cdev->name, cdev, &aspeed_pwm_cool_ops);
+	cdev->tcdev = devm_thermal_of_child_cooling_device_register(dev, child,
+								    cdev->name, cdev,
+								    &aspeed_pwm_cool_ops);
 	if (IS_ERR(cdev->tcdev))
 		return PTR_ERR(cdev->tcdev);
 
diff --git a/drivers/hwmon/emc2305.c b/drivers/hwmon/emc2305.c
index 64b213e1451e..2505e9fac499 100644
--- a/drivers/hwmon/emc2305.c
+++ b/drivers/hwmon/emc2305.c
@@ -309,9 +309,9 @@ static int emc2305_set_single_tz(struct device *dev, struct device_node *fan_nod
 	pwm = data->pwm_min[cdev_idx];
 
 	data->cdev_data[cdev_idx].cdev =
-		devm_thermal_of_cooling_device_register(dev, fan_node,
-							emc2305_fan_name[idx], data,
-							&emc2305_cooling_ops);
+		devm_thermal_of_child_cooling_device_register(dev, fan_node,
+							      emc2305_fan_name[idx], data,
+							      &emc2305_cooling_ops);
 
 	if (IS_ERR(data->cdev_data[cdev_idx].cdev)) {
 		dev_err(dev, "Failed to register cooling device %s\n", emc2305_fan_name[idx]);
diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c
index a8892ced1e54..084828e1e281 100644
--- a/drivers/hwmon/gpio-fan.c
+++ b/drivers/hwmon/gpio-fan.c
@@ -592,8 +592,10 @@ static int gpio_fan_probe(struct platform_device *pdev)
 	}
 
 	/* Optional cooling device register for Device tree platforms */
-	fan_data->cdev = devm_thermal_of_cooling_device_register(dev, np,
-				"gpio-fan", fan_data, &gpio_fan_cool_ops);
+	fan_data->cdev = devm_thermal_of_child_cooling_device_register(dev, np,
+								       "gpio-fan",
+								       fan_data,
+								       &gpio_fan_cool_ops);
 
 	dev_info(dev, "GPIO fan initialized\n");
 
diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c
index 9649c6611d5f..a50b1b0f1f48 100644
--- a/drivers/hwmon/max6650.c
+++ b/drivers/hwmon/max6650.c
@@ -793,9 +793,9 @@ static int max6650_probe(struct i2c_client *client)
 		return err;
 
 	if (IS_ENABLED(CONFIG_THERMAL)) {
-		cooling_dev = devm_thermal_of_cooling_device_register(dev,
-						dev->of_node, client->name,
-						data, &max6650_cooling_ops);
+		cooling_dev = devm_thermal_of_child_cooling_device_register(dev, dev->of_node,
+									    client->name, data,
+									    &max6650_cooling_ops);
 		if (IS_ERR(cooling_dev)) {
 			dev_warn(dev, "thermal cooling device register failed: %ld\n",
 				 PTR_ERR(cooling_dev));
diff --git a/drivers/hwmon/npcm750-pwm-fan.c b/drivers/hwmon/npcm750-pwm-fan.c
index c8f5e695fb6d..aea0b8659f5f 100644
--- a/drivers/hwmon/npcm750-pwm-fan.c
+++ b/drivers/hwmon/npcm750-pwm-fan.c
@@ -857,8 +857,10 @@ static int npcm7xx_create_pwm_cooling(struct device *dev,
 	snprintf(cdev->name, THERMAL_NAME_LENGTH, "%pOFn%d", child,
 		 pwm_port);
 
-	cdev->tcdev = devm_thermal_of_cooling_device_register(dev, child,
-				cdev->name, cdev, &npcm7xx_pwm_cool_ops);
+	cdev->tcdev = devm_thermal_of_child_cooling_device_register(dev, child,
+								    cdev->name,
+								    cdev,
+								    &npcm7xx_pwm_cool_ops);
 	if (IS_ERR(cdev->tcdev))
 		return PTR_ERR(cdev->tcdev);
 
diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c
index 37269db2de84..e6a567d58579 100644
--- a/drivers/hwmon/pwm-fan.c
+++ b/drivers/hwmon/pwm-fan.c
@@ -685,8 +685,9 @@ static int pwm_fan_probe(struct platform_device *pdev)
 
 	ctx->pwm_fan_state = ctx->pwm_fan_max_state;
 	if (IS_ENABLED(CONFIG_THERMAL)) {
-		cdev = devm_thermal_of_cooling_device_register(dev,
-			dev->of_node, "pwm-fan", ctx, &pwm_fan_cooling_ops);
+		cdev = devm_thermal_of_child_cooling_device_register(dev, dev->of_node,
+								     "pwm-fan", ctx,
+								     &pwm_fan_cooling_ops);
 		if (IS_ERR(cdev)) {
 			ret = PTR_ERR(cdev);
 			dev_err(dev,
diff --git a/drivers/hwmon/qnap-mcu-hwmon.c b/drivers/hwmon/qnap-mcu-hwmon.c
index e86e64c4d391..c1c1e9d6f340 100644
--- a/drivers/hwmon/qnap-mcu-hwmon.c
+++ b/drivers/hwmon/qnap-mcu-hwmon.c
@@ -337,9 +337,9 @@ static int qnap_mcu_hwmon_probe(struct platform_device *pdev)
 	 * levels and only succeed with either no or correct cooling levels.
 	 */
 	if (IS_ENABLED(CONFIG_THERMAL) && hwm->fan_cooling_levels) {
-		cdev = devm_thermal_of_cooling_device_register(dev,
-					to_of_node(hwm->fan_node), "qnap-mcu-hwmon",
-					hwm, &qnap_mcu_hwmon_cooling_ops);
+		cdev = devm_thermal_of_child_cooling_device_register(dev, to_of_node(hwm->fan_node),
+								     "qnap-mcu-hwmon", hwm,
+								     &qnap_mcu_hwmon_cooling_ops);
 		if (IS_ERR(cdev))
 			return dev_err_probe(dev, PTR_ERR(cdev),
 				"Failed to register qnap-mcu-hwmon as cooling device\n");
diff --git a/drivers/hwmon/tc654.c b/drivers/hwmon/tc654.c
index 39fe5836f237..ba18b442b81e 100644
--- a/drivers/hwmon/tc654.c
+++ b/drivers/hwmon/tc654.c
@@ -541,8 +541,9 @@ static int tc654_probe(struct i2c_client *client)
 	if (IS_ENABLED(CONFIG_THERMAL)) {
 		struct thermal_cooling_device *cdev;
 
-		cdev = devm_thermal_of_cooling_device_register(dev, dev->of_node, client->name,
-							       hwmon_dev, &tc654_fan_cool_ops);
+		cdev = devm_thermal_of_child_cooling_device_register(dev, dev->of_node,
+								     client->name, hwmon_dev,
+								     &tc654_fan_cool_ops);
 		return PTR_ERR_OR_ZERO(cdev);
 	}
 
diff --git a/drivers/memory/tegra/tegra210-emc-core.c b/drivers/memory/tegra/tegra210-emc-core.c
index e96ca4157d48..065ae8bc2830 100644
--- a/drivers/memory/tegra/tegra210-emc-core.c
+++ b/drivers/memory/tegra/tegra210-emc-core.c
@@ -1966,8 +1966,8 @@ static int tegra210_emc_probe(struct platform_device *pdev)
 
 	tegra210_emc_debugfs_init(emc);
 
-	cd = devm_thermal_of_cooling_device_register(emc->dev, np, "emc", emc,
-						     &tegra210_emc_cd_ops);
+	cd = devm_thermal_of_child_cooling_device_register(emc->dev, np, "emc", emc,
+							   &tegra210_emc_cd_ops);
 	if (IS_ERR(cd)) {
 		err = PTR_ERR(cd);
 		dev_err(emc->dev, "failed to register cooling device: %d\n",
diff --git a/drivers/soc/qcom/qcom_aoss.c b/drivers/soc/qcom/qcom_aoss.c
index a543ab9bee6c..742f571200fa 100644
--- a/drivers/soc/qcom/qcom_aoss.c
+++ b/drivers/soc/qcom/qcom_aoss.c
@@ -381,7 +381,7 @@ static int qmp_cooling_device_add(struct qmp *qmp,
 	qmp_cdev->qmp = qmp;
 	qmp_cdev->state = !qmp_cdev_max_state;
 	qmp_cdev->name = cdev_name;
-	qmp_cdev->cdev = devm_thermal_of_cooling_device_register
+	qmp_cdev->cdev = devm_thermal_of_child_cooling_device_register
 				(qmp->dev, node,
 				cdev_name,
 				qmp_cdev, &qmp_cooling_device_ops);
diff --git a/drivers/thermal/khadas_mcu_fan.c b/drivers/thermal/khadas_mcu_fan.c
index d35e5313bea4..21b3d0a71bd0 100644
--- a/drivers/thermal/khadas_mcu_fan.c
+++ b/drivers/thermal/khadas_mcu_fan.c
@@ -90,9 +90,10 @@ static int khadas_mcu_fan_probe(struct platform_device *pdev)
 	ctx->mcu = mcu;
 	platform_set_drvdata(pdev, ctx);
 
-	cdev = devm_thermal_of_cooling_device_register(dev->parent,
-			dev->parent->of_node, "khadas-mcu-fan", ctx,
-			&khadas_mcu_fan_cooling_ops);
+	cdev = devm_thermal_of_child_cooling_device_register(dev->parent,
+							     dev->parent->of_node,
+							     "khadas-mcu-fan", ctx,
+							     &khadas_mcu_fan_cooling_ops);
 	if (IS_ERR(cdev)) {
 		ret = PTR_ERR(cdev);
 		dev_err(dev, "Failed to register khadas-mcu-fan as cooling device: %d\n",
diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c
index 9d3eb3be2db0..9911f3ec0f40 100644
--- a/drivers/thermal/tegra/soctherm.c
+++ b/drivers/thermal/tegra/soctherm.c
@@ -1700,9 +1700,9 @@ static void soctherm_init_hw_throt_cdev(struct platform_device *pdev)
 			stc->init = true;
 		} else {
 
-			tcd = devm_thermal_of_cooling_device_register(dev, np_stcc,
-								      (char *)name, ts,
-								      &throt_cooling_ops);
+			tcd = devm_thermal_of_child_cooling_device_register(dev, np_stcc,
+									    (char *)name, ts,
+									    &throt_cooling_ops);
 			if (IS_ERR_OR_NULL(tcd)) {
 				dev_err(dev,
 					"throttle-cfg: %s: failed to register cooling device\n",
diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c
index 3d2fb8f37b9c..ba5093f612d0 100644
--- a/drivers/thermal/thermal_of.c
+++ b/drivers/thermal/thermal_of.c
@@ -550,7 +550,7 @@ static void thermal_cooling_device_release(struct device *dev, void *res)
 }
 
 /**
- * devm_thermal_of_cooling_device_register() - register an OF thermal cooling
+ * devm_thermal_of_child_cooling_device_register() - register an OF thermal cooling
  *					       device
  * @dev:	a valid struct device pointer of a sensor device.
  * @np:		a pointer to a device tree node.
@@ -567,10 +567,10 @@ static void thermal_cooling_device_release(struct device *dev, void *res)
  * ERR_PTR. Caller must check return value with IS_ERR*() helpers.
  */
 struct thermal_cooling_device *
-devm_thermal_of_cooling_device_register(struct device *dev,
-					struct device_node *np,
-					const char *type, void *devdata,
-					const struct thermal_cooling_device_ops *ops)
+devm_thermal_of_child_cooling_device_register(struct device *dev,
+					      struct device_node *np,
+					      const char *type, void *devdata,
+					      const struct thermal_cooling_device_ops *ops)
 {
 	struct thermal_cooling_device **ptr, *tcd;
 
@@ -590,4 +590,4 @@ devm_thermal_of_cooling_device_register(struct device *dev,
 
 	return tcd;
 }
-EXPORT_SYMBOL_GPL(devm_thermal_of_cooling_device_register);
+EXPORT_SYMBOL_GPL(devm_thermal_of_child_cooling_device_register);
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index a8e870ca2e27..6535353ae83c 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -206,10 +206,10 @@ thermal_of_cooling_device_register(struct device_node *np,
 				   const struct thermal_cooling_device_ops *ops);
 
 struct thermal_cooling_device *
-devm_thermal_of_cooling_device_register(struct device *dev,
-					struct device_node *np,
-					const char *type, void *devdata,
-					const struct thermal_cooling_device_ops *ops);
+devm_thermal_of_child_cooling_device_register(struct device *dev,
+					      struct device_node *np,
+					      const char *type, void *devdata,
+					      const struct thermal_cooling_device_ops *ops);
 #else
 
 static inline
@@ -233,10 +233,10 @@ thermal_of_cooling_device_register(struct device_node *np,
 }
 
 static inline struct thermal_cooling_device *
-devm_thermal_of_cooling_device_register(struct device *dev,
-					struct device_node *np,
-					const char *type, void *devdata,
-					const struct thermal_cooling_device_ops *ops)
+devm_thermal_of_child_cooling_device_register(struct device *dev,
+					      struct device_node *np,
+					      const char *type, void *devdata,
+					      const struct thermal_cooling_device_ops *ops)
 {
 	return ERR_PTR(-ENODEV);
 }
-- 
2.43.0


^ permalink raw reply related

* [PATCH v1 11/14] thermal/of: Introduce cooling device of_index
From: Daniel Lezcano @ 2026-04-19 18:21 UTC (permalink / raw)
  To: rafael
  Cc: gaurav.kohli, Zhang Rui, Lukasz Luba, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Lucas Stach, Russell King,
	Christian Gmeiner, David Airlie, Simona Vetter, Guenter Roeck,
	Joel Stanley, Andrew Jeffery, Thomas Weißschuh, Benson Leung,
	Pali Rohár, Avi Fishman, Tomer Maimon, Tali Perry,
	Patrick Venture, Nancy Yuen, Benjamin Fair, Heiko Stuebner,
	Thierry Reding, Jonathan Hunter, Bjorn Andersson, Konrad Dybcio,
	Amit Daniel Kachhap, Viresh Kumar, Neil Armstrong, Amit Kucheria,
	linux-pm, linux-kernel, linux-hwmon, Daniel Lezcano,
	moderated list:DRM DRIVERS FOR VIVANTE GPU IP,
	open list:DRM DRIVERS FOR VIVANTE GPU IP
In-Reply-To: <20260419182203.4083985-1-daniel.lezcano@oss.qualcomm.com>

As described in the previous change, the new incoming DT binding will
describe a tuple device_node + cooling device id, instead of child
nodes.

Let's augment thermal_of_cooling_device_register() to receive the
cooling device id and propagate the changes to the four remaining
drivers using the non-devm version of the cooling device registering
function.

Add the id in the cooling device structure and store the value when
registering it.

Signed-off-by: Daniel Lezcano <daniel.lezcano@oss.qualcomm.com>
---
 drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 2 +-
 drivers/thermal/cpufreq_cooling.c     | 2 +-
 drivers/thermal/cpuidle_cooling.c     | 2 +-
 drivers/thermal/devfreq_cooling.c     | 2 +-
 drivers/thermal/thermal_of.c          | 6 ++++--
 include/linux/thermal.h               | 5 +++--
 6 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
index a891d4f1f843..a965cc0633fc 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
@@ -1791,7 +1791,7 @@ static int etnaviv_gpu_bind(struct device *dev, struct device *master,
 	int ret;
 
 	if (IS_ENABLED(CONFIG_DRM_ETNAVIV_THERMAL)) {
-		gpu->cooling = thermal_of_cooling_device_register(dev->of_node,
+		gpu->cooling = thermal_of_cooling_device_register(dev->of_node, 0,
 				(char *)dev_name(dev), gpu, &cooling_ops);
 		if (IS_ERR(gpu->cooling))
 			return PTR_ERR(gpu->cooling);
diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c
index 32bf5ab44f4a..768859a7aed0 100644
--- a/drivers/thermal/cpufreq_cooling.c
+++ b/drivers/thermal/cpufreq_cooling.c
@@ -592,7 +592,7 @@ __cpufreq_cooling_register(struct device_node *np,
 	if (!name)
 		goto remove_qos_req;
 
-	cdev = thermal_of_cooling_device_register(np, name, cpufreq_cdev,
+	cdev = thermal_of_cooling_device_register(np, 0, name, cpufreq_cdev,
 						  cooling_ops);
 	kfree(name);
 
diff --git a/drivers/thermal/cpuidle_cooling.c b/drivers/thermal/cpuidle_cooling.c
index 425f596614e8..bbd2e91cf5ab 100644
--- a/drivers/thermal/cpuidle_cooling.c
+++ b/drivers/thermal/cpuidle_cooling.c
@@ -207,7 +207,7 @@ static int __cpuidle_cooling_register(struct device_node *np,
 		goto out_unregister;
 	}
 
-	cdev = thermal_of_cooling_device_register(np, name, idle_cdev,
+	cdev = thermal_of_cooling_device_register(np, 0, name, idle_cdev,
 						  &cpuidle_cooling_ops);
 	if (IS_ERR(cdev)) {
 		ret = PTR_ERR(cdev);
diff --git a/drivers/thermal/devfreq_cooling.c b/drivers/thermal/devfreq_cooling.c
index 1c7dffc8d45f..0330a8112832 100644
--- a/drivers/thermal/devfreq_cooling.c
+++ b/drivers/thermal/devfreq_cooling.c
@@ -454,7 +454,7 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df,
 	if (!name)
 		goto remove_qos_req;
 
-	cdev = thermal_of_cooling_device_register(np, name, dfc, ops);
+	cdev = thermal_of_cooling_device_register(np, 0, name, dfc, ops);
 	kfree(name);
 
 	if (IS_ERR(cdev)) {
diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c
index ba5093f612d0..a728da1f4e56 100644
--- a/drivers/thermal/thermal_of.c
+++ b/drivers/thermal/thermal_of.c
@@ -514,6 +514,7 @@ EXPORT_SYMBOL_GPL(devm_thermal_of_zone_unregister);
 /**
  * thermal_of_cooling_device_register() - register an OF thermal cooling device
  * @np:		a pointer to a device tree node.
+ * @of_index:	a cooling device index in the cooling controller
  * @type:	the thermal cooling device type.
  * @devdata:	device private data.
  * @ops:		standard thermal cooling devices callbacks.
@@ -527,7 +528,7 @@ EXPORT_SYMBOL_GPL(devm_thermal_of_zone_unregister);
  * ERR_PTR. Caller must check return value with IS_ERR*() helpers.
  */
 struct thermal_cooling_device *
-thermal_of_cooling_device_register(struct device_node *np,
+thermal_of_cooling_device_register(struct device_node *np, int of_index,
 				   const char *type, void *devdata,
 				   const struct thermal_cooling_device_ops *ops)
 {
@@ -538,6 +539,7 @@ thermal_of_cooling_device_register(struct device_node *np,
 		return cdev;
 
 	cdev->np = np;
+	cdev->of_index = of_index;
 	thermal_cooling_device_init_complete(cdev);
 
 	return cdev;
@@ -579,7 +581,7 @@ devm_thermal_of_child_cooling_device_register(struct device *dev,
 	if (!ptr)
 		return ERR_PTR(-ENOMEM);
 
-	tcd = thermal_of_cooling_device_register(np, type, devdata, ops);
+	tcd = thermal_of_cooling_device_register(np, 0, type, devdata, ops);
 	if (IS_ERR(tcd)) {
 		devres_free(ptr);
 		return tcd;
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 6535353ae83c..9813f02db088 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -134,6 +134,7 @@ struct thermal_cooling_device {
 	struct list_head node;
 #ifdef CONFIG_THERMAL_OF
 	struct device_node *np;
+	int of_index;
 #endif
 #ifdef CONFIG_THERMAL_DEBUGFS
 	struct thermal_debugfs *debugfs;
@@ -201,7 +202,7 @@ struct thermal_zone_device *devm_thermal_of_zone_register(struct device *dev, in
 void devm_thermal_of_zone_unregister(struct device *dev, struct thermal_zone_device *tz);
 
 struct thermal_cooling_device *
-thermal_of_cooling_device_register(struct device_node *np,
+thermal_of_cooling_device_register(struct device_node *np, int of_index,
 				   const char *type, void *data,
 				   const struct thermal_cooling_device_ops *ops);
 
@@ -225,7 +226,7 @@ static inline void devm_thermal_of_zone_unregister(struct device *dev,
 }
 
 static inline struct thermal_cooling_device *
-thermal_of_cooling_device_register(struct device_node *np,
+thermal_of_cooling_device_register(struct device_node *np, int of_index,
 				   const char *type, void *devdata,
 				   const struct thermal_cooling_device_ops *ops)
 {
-- 
2.43.0


^ permalink raw reply related

* [PATCH v1 12/14] thermal/of: Pass the of_index and add a function to register with an index
From: Daniel Lezcano @ 2026-04-19 18:21 UTC (permalink / raw)
  To: rafael
  Cc: gaurav.kohli, Zhang Rui, Lukasz Luba, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Lucas Stach, Russell King,
	Christian Gmeiner, David Airlie, Simona Vetter, Guenter Roeck,
	Joel Stanley, Andrew Jeffery, Thomas Weißschuh, Benson Leung,
	Pali Rohár, Avi Fishman, Tomer Maimon, Tali Perry,
	Patrick Venture, Nancy Yuen, Benjamin Fair, Heiko Stuebner,
	Thierry Reding, Jonathan Hunter, Bjorn Andersson, Konrad Dybcio,
	Amit Daniel Kachhap, Viresh Kumar, Neil Armstrong, Amit Kucheria,
	linux-pm, linux-kernel, linux-hwmon, Daniel Lezcano
In-Reply-To: <20260419182203.4083985-1-daniel.lezcano@oss.qualcomm.com>

Introduce a new function devm_thermal_of_cooling_device_register()
which will register a cooling device and its id.

Signed-off-by: Daniel Lezcano <daniel.lezcano@oss.qualcomm.com>
---
 drivers/thermal/thermal_of.c | 68 +++++++++++++++++++++++++++---------
 include/linux/thermal.h      | 13 +++++++
 2 files changed, 64 insertions(+), 17 deletions(-)

diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c
index a728da1f4e56..d9bd7dc01e19 100644
--- a/drivers/thermal/thermal_of.c
+++ b/drivers/thermal/thermal_of.c
@@ -551,6 +551,56 @@ static void thermal_cooling_device_release(struct device *dev, void *res)
 	thermal_cooling_device_unregister(*(struct thermal_cooling_device **)res);
 }
 
+static struct thermal_cooling_device *
+__devm_thermal_of_cooling_device_register(struct device *dev, struct device_node *np,
+					  int of_index, const char *type, void *devdata,
+					  const struct thermal_cooling_device_ops *ops)
+{
+	struct thermal_cooling_device **ptr, *tcd;
+
+	ptr = devres_alloc(thermal_cooling_device_release, sizeof(*ptr),
+			   GFP_KERNEL);
+	if (!ptr)
+		return ERR_PTR(-ENOMEM);
+
+	tcd = thermal_of_cooling_device_register(np, of_index, type, devdata, ops);
+	if (IS_ERR(tcd)) {
+		devres_free(ptr);
+		return tcd;
+	}
+
+	*ptr = tcd;
+	devres_add(dev, ptr);
+
+	return tcd;
+}
+
+/**
+ * devm_thermal_of_cooling_device_register() - register an OF thermal cooling device
+ * @dev:	a valid struct device pointer of a sensor device.
+ * @of_index:	a cooling device index in the cooling controller
+ * @type:	the thermal cooling device type.
+ * @devdata:	device private data.
+ * @ops:	standard thermal cooling devices callbacks.
+ *
+ * This function will register a cooling device with device tree node reference.
+ * This interface function adds a new thermal cooling device (fan/processor/...)
+ * to /sys/class/thermal/ folder as cooling_device[0-*]. It tries to bind itself
+ * to all the thermal zone devices registered at the same time.
+ *
+ * Return: a pointer to the created struct thermal_cooling_device or an
+ * ERR_PTR. Caller must check return value with IS_ERR*() helpers.
+ */
+struct thermal_cooling_device *
+devm_thermal_of_cooling_device_register(struct device *dev, int of_index,
+					const char *type, void *devdata,
+					const struct thermal_cooling_device_ops *ops)
+{
+	return __devm_thermal_of_cooling_device_register(dev, dev->of_node, of_index,
+							 type, devdata, ops);
+}
+EXPORT_SYMBOL_GPL(devm_thermal_of_cooling_device_register);
+
 /**
  * devm_thermal_of_child_cooling_device_register() - register an OF thermal cooling
  *					       device
@@ -574,22 +624,6 @@ devm_thermal_of_child_cooling_device_register(struct device *dev,
 					      const char *type, void *devdata,
 					      const struct thermal_cooling_device_ops *ops)
 {
-	struct thermal_cooling_device **ptr, *tcd;
-
-	ptr = devres_alloc(thermal_cooling_device_release, sizeof(*ptr),
-			   GFP_KERNEL);
-	if (!ptr)
-		return ERR_PTR(-ENOMEM);
-
-	tcd = thermal_of_cooling_device_register(np, 0, type, devdata, ops);
-	if (IS_ERR(tcd)) {
-		devres_free(ptr);
-		return tcd;
-	}
-
-	*ptr = tcd;
-	devres_add(dev, ptr);
-
-	return tcd;
+	return __devm_thermal_of_cooling_device_register(dev, np, 0, type, devdata, ops);
 }
 EXPORT_SYMBOL_GPL(devm_thermal_of_child_cooling_device_register);
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 9813f02db088..b7e5496f3e78 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -206,6 +206,11 @@ thermal_of_cooling_device_register(struct device_node *np, int of_index,
 				   const char *type, void *data,
 				   const struct thermal_cooling_device_ops *ops);
 
+struct thermal_cooling_device *
+devm_thermal_of_cooling_device_register(struct device *dev, int of_index,
+					const char *type, void *devdata,
+					const struct thermal_cooling_device_ops *ops);
+
 struct thermal_cooling_device *
 devm_thermal_of_child_cooling_device_register(struct device *dev,
 					      struct device_node *np,
@@ -233,6 +238,14 @@ thermal_of_cooling_device_register(struct device_node *np, int of_index,
 	return ERR_PTR(-ENODEV);
 }
 
+static inline struct thermal_cooling_device *
+devm_thermal_of_cooling_device_register(struct device *dev, int of_index,
+					const char *type, void *devdata,
+					const struct thermal_cooling_device_ops *ops)
+{
+	return ERR_PTR(-ENODEV);
+}
+
 static inline struct thermal_cooling_device *
 devm_thermal_of_child_cooling_device_register(struct device *dev,
 					      struct device_node *np,
-- 
2.43.0


^ permalink raw reply related

* [PATCH v1 13/14] thermal/of: Process cooling device index in cooling-spec
From: Daniel Lezcano @ 2026-04-19 18:21 UTC (permalink / raw)
  To: rafael
  Cc: gaurav.kohli, Zhang Rui, Lukasz Luba, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Lucas Stach, Russell King,
	Christian Gmeiner, David Airlie, Simona Vetter, Guenter Roeck,
	Joel Stanley, Andrew Jeffery, Thomas Weißschuh, Benson Leung,
	Pali Rohár, Avi Fishman, Tomer Maimon, Tali Perry,
	Patrick Venture, Nancy Yuen, Benjamin Fair, Heiko Stuebner,
	Thierry Reding, Jonathan Hunter, Bjorn Andersson, Konrad Dybcio,
	Amit Daniel Kachhap, Viresh Kumar, Neil Armstrong, Amit Kucheria,
	linux-pm, linux-kernel, linux-hwmon, Daniel Lezcano
In-Reply-To: <20260419182203.4083985-1-daniel.lezcano@oss.qualcomm.com>

The new DT bindings format describes a cooling device spec with the
cooling device node, the id and the mitigation limits.

Depending on the version of the DT bindings, in order to bind, check
with the device node pointer only or, in addition, the cooling device
id.

Signed-off-by: Daniel Lezcano <daniel.lezcano@oss.qualcomm.com>
---
 drivers/thermal/thermal_of.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c
index d9bd7dc01e19..e9b39d625b0c 100644
--- a/drivers/thermal/thermal_of.c
+++ b/drivers/thermal/thermal_of.c
@@ -264,11 +264,29 @@ static bool thermal_of_get_cooling_spec(struct device_node *map_np, int index,
 		return false;
 	}
 
+	/*
+	 * There are two formats:
+	 * - Legacy format :	<&cdev lower upper>
+	 * - New format    :	<&cdev of_index lower upper>
+	 *
+	 * With the new format, along with the device node pointer,
+	 * the of_index must match with the cooling device of_index in
+	 * order to bind
+	 */
+	if (cooling_spec.args_count == 3 &&
+	    cooling_spec.args[0] != cdev->of_index)
+		return false;
+
 	if (cooling_spec.np != cdev->np)
 		return false;
 
-	c->lower = cooling_spec.args[0];
-	c->upper = cooling_spec.args[1];
+	if (cooling_spec.args_count != 3) {
+		c->lower = cooling_spec.args[0];
+		c->upper = cooling_spec.args[1];
+	} else {
+		c->lower = cooling_spec.args[1];
+		c->upper = cooling_spec.args[2];
+	}
 	c->weight = weight;
 
 	return true;
-- 
2.43.0


^ permalink raw reply related

* [PATCH v1 14/14] dt-bindings: thermal: cooling-devices: Update support for 3 cells cooling device
From: Daniel Lezcano @ 2026-04-19 18:21 UTC (permalink / raw)
  To: rafael
  Cc: gaurav.kohli, Zhang Rui, Lukasz Luba, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Lucas Stach, Russell King,
	Christian Gmeiner, David Airlie, Simona Vetter, Guenter Roeck,
	Joel Stanley, Andrew Jeffery, Thomas Weißschuh, Benson Leung,
	Pali Rohár, Avi Fishman, Tomer Maimon, Tali Perry,
	Patrick Venture, Nancy Yuen, Benjamin Fair, Heiko Stuebner,
	Thierry Reding, Jonathan Hunter, Bjorn Andersson, Konrad Dybcio,
	Amit Daniel Kachhap, Viresh Kumar, Neil Armstrong, Amit Kucheria,
	linux-pm, linux-kernel, linux-hwmon, Daniel Lezcano,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
In-Reply-To: <20260419182203.4083985-1-daniel.lezcano@oss.qualcomm.com>

From: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>

Extend the thermal cooling device binding to support a 3 cells specifier
along with tje 2 cells format.

Update #cooling-cells property to enum to support both 2 and 3 arguments.

Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@oss.qualcomm.com>
---
 .../bindings/thermal/thermal-cooling-devices.yaml         | 8 ++++++--
 .../devicetree/bindings/thermal/thermal-zones.yaml        | 3 ++-
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml b/Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml
index b9022f1613d8..28f5818f1e60 100644
--- a/Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml
+++ b/Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml
@@ -44,10 +44,14 @@ select: true
 properties:
   "#cooling-cells":
     description:
-      Must be 2, in order to specify minimum and maximum cooling state used in
+      Must be 2 or 3. If 2, specifies minimum and maximum cooling state used in
       the cooling-maps reference. The first cell is the minimum cooling state
       and the second cell is the maximum cooling state requested.
-    const: 2
+      If 3, the first cell specifies the thermal mitigation device specifier
+      index for devices that support multiple thermal mitigation mechanisms.
+      The two other cells are respectively the minimum cooling state and the
+      maximum cooling state.
+    enum: [2, 3]
 
 additionalProperties: true
 
diff --git a/Documentation/devicetree/bindings/thermal/thermal-zones.yaml b/Documentation/devicetree/bindings/thermal/thermal-zones.yaml
index 0de0a9757ccc..1261ba0e802e 100644
--- a/Documentation/devicetree/bindings/thermal/thermal-zones.yaml
+++ b/Documentation/devicetree/bindings/thermal/thermal-zones.yaml
@@ -214,7 +214,8 @@ patternProperties:
                   device. Using the THERMAL_NO_LIMIT (-1UL) constant in the
                   cooling-device phandle limit specifier lets the framework
                   use the minimum and maximum cooling state for that cooling
-                  device automatically.
+                  device automatically. If three arguments are specified,
+                  the first argument is the cooling device specifier.
 
               contribution:
                 $ref: /schemas/types.yaml#/definitions/uint32
-- 
2.43.0


^ permalink raw reply related

* [PATCH 0/2] Add interconnect support for Qualcomm Nord SoC
From: Shawn Guo @ 2026-04-20  2:13 UTC (permalink / raw)
  To: Georgi Djakov
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Dmitry Baryshkov,
	Odelu Kukatla, Konrad Dybcio, Bartosz Golaszewski, Deepti Jaggi,
	linux-arm-msm, linux-pm, devicetree, linux-kernel, Shawn Guo

This series adds RPMh-based interconnect support for the Qualcomm Nord SoC.

The Nord SoC features a rich Network-on-Chip topology comprising 19 NoCs
including aggregate NoCs, a high-speed configuration NoC (HSCNOC),
a multimedia NoC, four NSP data NoCs for AI/ML workloads, PCIe inbound and
outbound NoCs, a system NoC, and virtual clock/MC nodes. Bandwidth requests
are communicated to the RPMh hardware through Bus Clock Manager (BCM)
resources via the Resource State Coordinator (RSC).

Odelu Kukatla (2):
  dt-bindings: interconnect: Document RPMh Network-On-Chip for Qualcomm
    Nord SoC
  interconnect: qcom: Add interconnect provider driver for Nord SoC

 .../bindings/interconnect/qcom,nord-rpmh.yaml |  131 +
 drivers/interconnect/qcom/Kconfig             |   11 +
 drivers/interconnect/qcom/Makefile            |    2 +
 drivers/interconnect/qcom/nord.c              | 2682 +++++++++++++++++
 .../dt-bindings/interconnect/qcom,nord-rpmh.h |  217 ++
 5 files changed, 3043 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,nord-rpmh.yaml
 create mode 100644 drivers/interconnect/qcom/nord.c
 create mode 100644 include/dt-bindings/interconnect/qcom,nord-rpmh.h

-- 
2.43.0


^ permalink raw reply

* [PATCH 1/2] dt-bindings: interconnect: Document RPMh Network-On-Chip for Qualcomm Nord SoC
From: Shawn Guo @ 2026-04-20  2:13 UTC (permalink / raw)
  To: Georgi Djakov
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Dmitry Baryshkov,
	Odelu Kukatla, Konrad Dybcio, Bartosz Golaszewski, Deepti Jaggi,
	linux-arm-msm, linux-pm, devicetree, linux-kernel, Shawn Guo
In-Reply-To: <20260420021351.1239355-1-shengchao.guo@oss.qualcomm.com>

From: Odelu Kukatla <odelu.kukatla@oss.qualcomm.com>

Add RPMh Network-On-Chip interconnect bindings for Qualcomm Nord SoC.

Signed-off-by: Odelu Kukatla <odelu.kukatla@oss.qualcomm.com>
Signed-off-by: Shawn Guo <shengchao.guo@oss.qualcomm.com>
---
 .../bindings/interconnect/qcom,nord-rpmh.yaml | 131 +++++++++++
 .../dt-bindings/interconnect/qcom,nord-rpmh.h | 217 ++++++++++++++++++
 2 files changed, 348 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,nord-rpmh.yaml
 create mode 100644 include/dt-bindings/interconnect/qcom,nord-rpmh.h

diff --git a/Documentation/devicetree/bindings/interconnect/qcom,nord-rpmh.yaml b/Documentation/devicetree/bindings/interconnect/qcom,nord-rpmh.yaml
new file mode 100644
index 000000000000..3650d3d5b918
--- /dev/null
+++ b/Documentation/devicetree/bindings/interconnect/qcom,nord-rpmh.yaml
@@ -0,0 +1,131 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interconnect/qcom,nord-rpmh.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm RPMh Network-On-Chip Interconnect on Nord
+
+maintainers:
+  - Odelu Kukatla <odelu.kukatla@oss.qualcomm.com>
+
+description: |
+  RPMh interconnect providers support system bandwidth requirements through
+  RPMh hardware accelerators known as Bus Clock Manager (BCM). The provider is
+  able to communicate with the BCM through the Resource State Coordinator (RSC)
+  associated with each execution environment. Provider nodes must point to at
+  least one RPMh device child node pertaining to their RSC and each provider
+  can map to multiple RPMh resources.
+
+  See also: include/dt-bindings/interconnect/qcom,nord-rpmh.h
+
+properties:
+  compatible:
+    enum:
+      - qcom,nord-aggre1-noc
+      - qcom,nord-aggre1-noc-tile
+      - qcom,nord-aggre2-noc
+      - qcom,nord-aggre2-noc-tile
+      - qcom,nord-clk-virt
+      - qcom,nord-cnoc-cfg
+      - qcom,nord-cnoc-main
+      - qcom,nord-hpass-ag-noc
+      - qcom,nord-hscnoc
+      - qcom,nord-mc-virt
+      - qcom,nord-mmss-noc
+      - qcom,nord-nsp-data-noc-0
+      - qcom,nord-nsp-data-noc-1
+      - qcom,nord-nsp-data-noc-2
+      - qcom,nord-nsp-data-noc-3
+      - qcom,nord-pcie-cfg
+      - qcom,nord-pcie-data-inbound
+      - qcom,nord-pcie-data-outbound
+      - qcom,nord-system-noc
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    minItems: 1
+    maxItems: 4
+
+required:
+  - compatible
+
+allOf:
+  - $ref: qcom,rpmh-common.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,nord-clk-virt
+              - qcom,nord-mc-virt
+    then:
+      properties:
+        reg: false
+    else:
+      required:
+        - reg
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,nord-aggre1-noc-tile
+    then:
+      properties:
+        clocks:
+          items:
+            - description: aggre UFS PHY AXI clock
+            - description: aggre USB2 AXI clock
+            - description: aggre USB3 PRIM AXI clock
+            - description: aggre USB3 SEC AXI clock
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,nord-aggre2-noc
+    then:
+      properties:
+        clocks:
+          items:
+            - description: RPMH CC IPA clock
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,nord-aggre1-noc-tile
+              - qcom,nord-aggre2-noc
+    then:
+      required:
+        - clocks
+    else:
+      properties:
+        clocks: false
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    clk_virt: interconnect-clk-virt {
+      compatible = "qcom,nord-clk-virt";
+      #interconnect-cells = <2>;
+      qcom,bcm-voters = <&apps_bcm_voter>;
+    };
+
+    aggre1_noc_tile: interconnect@1720000 {
+      compatible = "qcom,nord-aggre1-noc-tile";
+      reg = <0x01720000 0x23400>;
+      #interconnect-cells = <2>;
+      qcom,bcm-voters = <&apps_bcm_voter>;
+      clocks = <&ne_gcc_aggre_noc_ufs_phy_axi_clk>,
+               <&ne_gcc_aggre_noc_usb2_axi_clk>,
+               <&ne_gcc_aggre_noc_usb3_prim_axi_clk>,
+               <&ne_gcc_aggre_noc_usb3_sec_axi_clk>;
+    };
diff --git a/include/dt-bindings/interconnect/qcom,nord-rpmh.h b/include/dt-bindings/interconnect/qcom,nord-rpmh.h
new file mode 100644
index 000000000000..5bdce6a9bab7
--- /dev/null
+++ b/include/dt-bindings/interconnect/qcom,nord-rpmh.h
@@ -0,0 +1,217 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef __DT_BINDINGS_INTERCONNECT_QCOM_NORD_H
+#define __DT_BINDINGS_INTERCONNECT_QCOM_NORD_H
+
+#define MASTER_QSPI_0				0
+#define MASTER_SAILSS_MD1			1
+#define MASTER_QUP_3				2
+#define SLAVE_A1NOC_SNOC			3
+
+#define MASTER_QUP_2				0
+#define MASTER_CRYPTO_CORE0			1
+#define MASTER_CRYPTO_CORE1			2
+#define MASTER_CRYPTO_CORE2			3
+#define MASTER_SDCC_4				4
+#define MASTER_UFS_MEM				5
+#define MASTER_USB2				6
+#define MASTER_USB3_0				7
+#define MASTER_USB3_1				8
+#define SLAVE_A1NOC_HSCNOC			9
+
+#define MASTER_IPA				0
+#define MASTER_SOCCP_AGGR_NOC			1
+#define MASTER_QDSS_ETR				2
+#define MASTER_QDSS_ETR_1			3
+#define SLAVE_A2NOC_SNOC			4
+
+#define MASTER_QUP_0				0
+#define MASTER_QUP_1				1
+#define MASTER_EMAC_0				2
+#define MASTER_EMAC_1				3
+#define SLAVE_A2NOC_HSCNOC			4
+
+#define MASTER_QUP_CORE_0			0
+#define MASTER_QUP_CORE_1			1
+#define MASTER_QUP_CORE_2			2
+#define MASTER_QUP_CORE_3			3
+#define SLAVE_QUP_CORE_0			4
+#define SLAVE_QUP_CORE_1			5
+#define SLAVE_QUP_CORE_2			6
+#define SLAVE_QUP_CORE_3			7
+
+#define MASTER_CNOC_CFG				0
+#define SLAVE_PS_ETH_0				1
+#define SLAVE_PS_ETH_1				2
+#define SLAVE_SHS_SERVER			3
+#define SLAVE_AHB2PHY_0				4
+#define SLAVE_AHB2PHY_1				5
+#define SLAVE_AHB2PHY_2				6
+#define SLAVE_AHB2PHY_3				7
+#define SLAVE_AHB2PHY_ETH_0			8
+#define SLAVE_AHB2PHY_ETH_1			9
+#define SLAVE_CAMERA_CFG			10
+#define SLAVE_CLK_CTL				11
+#define SLAVE_CRYPTO_0_CFG			12
+#define SLAVE_CRYPTO_1_CFG			13
+#define SLAVE_CRYPTO_2_CFG			14
+#define SLAVE_DISPLAY_1_CFG			15
+#define SLAVE_DISPLAY_CFG			16
+#define SLAVE_DPRX0				17
+#define SLAVE_DPRX1				18
+#define SLAVE_EVA_CFG				19
+#define SLAVE_GFX3D_CFG				20
+#define SLAVE_GFX3D_1_CFG			21
+#define SLAVE_I2C				22
+#define SLAVE_IMEM_CFG				23
+#define SLAVE_MCW_PCIE				24
+#define SLAVE_MM_RSCC				25
+#define SLAVE_NE_CLK_CTL			26
+#define SLAVE_NSPSS0_CFG			27
+#define SLAVE_NSPSS1_CFG			28
+#define SLAVE_NSPSS2_CFG			29
+#define SLAVE_NSPSS3_CFG			30
+#define SLAVE_NW_CLK_CTL			31
+#define SLAVE_PRNG				32
+#define SLAVE_QDSS_CFG				33
+#define SLAVE_QSPI_0				34
+#define SLAVE_QUP_0				35
+#define SLAVE_QUP_3				36
+#define SLAVE_QUP_1				37
+#define SLAVE_QUP_2				38
+#define SLAVE_SAFEDMA_CFG			39
+#define SLAVE_SDCC_4				40
+#define SLAVE_SE_CLK_CTL			41
+#define SLAVE_TCSR				42
+#define SLAVE_TLMM				43
+#define SLAVE_TSC_CFG				44
+#define SLAVE_UFS_MEM_CFG			45
+#define SLAVE_USB2				46
+#define SLAVE_USB3_0				47
+#define SLAVE_USB3_1				48
+#define SLAVE_VENUS_CFG				49
+#define SLAVE_COMPUTENOC_CFG			50
+#define SLAVE_PCIE_NOC_CFG			51
+#define SLAVE_QTC_CFG				52
+#define SLAVE_QDSS_STM				53
+#define SLAVE_SYS_TCU0_CFG			54
+#define SLAVE_SYS_TCU1_CFG			55
+#define SLAVE_SYS_TCU2_CFG			56
+
+#define MASTER_MM_RSCC				0
+#define MASTER_HSCNOC_CNOC			1
+#define SLAVE_AOSS				2
+#define SLAVE_HBCU				3
+#define SLAVE_IPA_CFG				4
+#define SLAVE_IPC_ROUTER_CFG			5
+#define SLAVE_SOCCP				6
+#define SLAVE_TME_CFG				7
+#define SLAVE_PCIE_DMA				8
+#define SLAVE_CNOC_CFG				9
+#define SLAVE_DDRSS_CFG				10
+#define SLAVE_IMEM				11
+
+#define MASTER_HPASS_PROC_0			0
+#define MASTER_HPASS_PROC_1			1
+#define MASTER_HPASS_PROC_2			2
+#define SLAVE_HPASS_AGNOC_AUDIO			3
+
+#define MASTER_GPU_TCU				0
+#define MASTER_QTC_TCU				1
+#define MASTER_SYS_TCU_0			2
+#define MASTER_SYS_TCU_1			3
+#define MASTER_SYS_TCU_2			4
+#define MASTER_APPSS_PROC			5
+#define MASTER_A1NOC_TILE_HSCNOC		6
+#define MASTER_A2NOC_TILE_HSCNOC		7
+#define MASTER_GFX3D				8
+#define MASTER_GFX3D_1				9
+#define MASTER_HPASS_ADAS_HSCNOC		10
+#define MASTER_HPASS_AUDIO_HSCNOC		11
+#define MASTER_MNOC_HF_MEM_NOC			12
+#define MASTER_MNOC_SF_MEM_NOC			13
+#define MASTER_NSP0_HSCNOC			14
+#define MASTER_NSP1_HSCNOC			15
+#define MASTER_NSP2_HSCNOC			16
+#define MASTER_NSP3_HSCNOC			17
+#define MASTER_ANOC_PCIE_GEM_NOC		18
+#define MASTER_SAILSS_MD0_HSCNOC		19
+#define MASTER_SNOC_SF_MEM_NOC			20
+#define MASTER_GIC				21
+#define SLAVE_HSCNOC_CNOC			22
+#define SLAVE_LLCC				23
+#define SLAVE_MEM_NOC_PCIE_SNOC			24
+
+#define MASTER_LLCC				0
+#define SLAVE_EBI1				1
+
+#define MASTER_CAMNOC_HF			0
+#define MASTER_CAMNOC_NRT_ICP_SF		1
+#define MASTER_CAMNOC_RT_CDM_SF			2
+#define MASTER_CAMNOC_SF			3
+#define MASTER_DPRX0				4
+#define MASTER_DPRX1				5
+#define MASTER_MDP0				6
+#define MASTER_MDP1				7
+#define MASTER_VIDEO_CV_PROC			8
+#define MASTER_VIDEO_EVA			9
+#define MASTER_VIDEO_MVP0			10
+#define MASTER_VIDEO_MVP1			11
+#define MASTER_VIDEO_V_PROC			12
+#define SLAVE_MNOC_HF_MEM_NOC			13
+#define SLAVE_MNOC_SF_MEM_NOC			14
+
+#define MASTER_NSP0_PROC			0
+#define SLAVE_NSP0_HSC_NOC			1
+
+#define MASTER_NSP1_PROC			0
+#define SLAVE_NSP1_HSC_NOC			1
+
+#define MASTER_NSP2_PROC			0
+#define SLAVE_NSP2_HSC_NOC			1
+
+#define MASTER_NSP3_PROC			0
+#define SLAVE_NSP3_HSC_NOC			1
+
+#define MASTER_PCIE_NOC_CFG			0
+#define SLAVE_PCIE_AHB2PHY_CFG			1
+#define SLAVE_PCIE_CFG_0			2
+#define SLAVE_PCIE_CFG_1			3
+#define SLAVE_PCIE_CFG_2			4
+#define SLAVE_PCIE_CFG_3			5
+#define SLAVE_PCIE_DMA_0_CFG			6
+#define SLAVE_PCIE_DMA_1_CFG			7
+#define SLAVE_PCIE_DMA_2_CFG			8
+
+#define MASTER_PCIE_DMA_0			0
+#define MASTER_PCIE_DMA_1			1
+#define MASTER_PCIE_DMA_2			2
+#define MASTER_PCIE_0				3
+#define MASTER_PCIE_1				4
+#define MASTER_PCIE_2				5
+#define MASTER_PCIE_3				6
+#define SLAVE_PCIE_HSCNOC			7
+#define SLAVE_PCIE_OBNOC_DMA			8
+
+#define MASTER_CNOC_PCIE_DMA			0
+#define MASTER_ANOC_PCIE_HSCNOC			1
+#define MASTER_PCIE_IBNOC_DMA			2
+#define SLAVE_PCIE_DMA_0			3
+#define SLAVE_PCIE_DMA_1			4
+#define SLAVE_PCIE_DMA_2			5
+#define SLAVE_PCIE_0				6
+#define SLAVE_PCIE_1				7
+#define SLAVE_PCIE_2				8
+#define SLAVE_PCIE_3				9
+
+#define MASTER_A1NOC_SNOC			0
+#define MASTER_A2NOC_SNOC			1
+#define MASTER_CNOC_SNOC			2
+#define MASTER_NSINOC_SNOC			3
+#define MASTER_SAFE_DMA				4
+#define SLAVE_SNOC_HSCNOC_SF			5
+
+#endif
-- 
2.43.0


^ permalink raw reply related

* [PATCH 2/2] interconnect: qcom: Add interconnect provider driver for Nord SoC
From: Shawn Guo @ 2026-04-20  2:13 UTC (permalink / raw)
  To: Georgi Djakov
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Dmitry Baryshkov,
	Odelu Kukatla, Konrad Dybcio, Bartosz Golaszewski, Deepti Jaggi,
	linux-arm-msm, linux-pm, devicetree, linux-kernel, Shawn Guo
In-Reply-To: <20260420021351.1239355-1-shengchao.guo@oss.qualcomm.com>

From: Odelu Kukatla <odelu.kukatla@oss.qualcomm.com>

Add driver for the Qualcomm interconnect buses found on Nord SoC.
The topology consists of several NoCs that are controlled by
a remote processor that collects the aggregated bandwidth for each
master-slave pair.

Signed-off-by: Odelu Kukatla <odelu.kukatla@oss.qualcomm.com>
Signed-off-by: Shawn Guo <shengchao.guo@oss.qualcomm.com>
---
 drivers/interconnect/qcom/Kconfig  |   11 +
 drivers/interconnect/qcom/Makefile |    2 +
 drivers/interconnect/qcom/nord.c   | 2682 ++++++++++++++++++++++++++++
 3 files changed, 2695 insertions(+)
 create mode 100644 drivers/interconnect/qcom/nord.c

diff --git a/drivers/interconnect/qcom/Kconfig b/drivers/interconnect/qcom/Kconfig
index 786b4eda44b4..32808772c363 100644
--- a/drivers/interconnect/qcom/Kconfig
+++ b/drivers/interconnect/qcom/Kconfig
@@ -107,6 +107,17 @@ config INTERCONNECT_QCOM_MSM8996
 	  This is a driver for the Qualcomm Network-on-Chip on msm8996-based
 	  platforms.
 
+config INTERCONNECT_QCOM_NORD
+	tristate "Qualcomm Nord interconnect driver"
+	depends on INTERCONNECT_QCOM_RPMH_POSSIBLE
+	select INTERCONNECT_QCOM_RPMH
+	select INTERCONNECT_QCOM_BCM_VOTER
+	help
+	  This is a driver for the Qualcomm Network-on-Chip on Nord-based
+	  platforms. The topology consists of several NoCs controlled by
+	  the RPMh hardware and communicates via Bus Clock Manager (BCM)
+	  through the Resource State Coordinator (RSC).
+
 config INTERCONNECT_QCOM_OSM_L3
 	tristate "Qualcomm OSM L3 interconnect driver"
 	depends on INTERCONNECT_QCOM || COMPILE_TEST
diff --git a/drivers/interconnect/qcom/Makefile b/drivers/interconnect/qcom/Makefile
index cdf2c6c9fbf3..988fa8b0f509 100644
--- a/drivers/interconnect/qcom/Makefile
+++ b/drivers/interconnect/qcom/Makefile
@@ -16,6 +16,7 @@ qnoc-msm8953-objs			:= msm8953.o
 qnoc-msm8974-objs			:= msm8974.o
 qnoc-msm8976-objs			:= msm8976.o
 qnoc-msm8996-objs			:= msm8996.o
+qnoc-nord-objs				:= nord.o
 icc-osm-l3-objs				:= osm-l3.o
 qnoc-qcm2290-objs			:= qcm2290.o
 qnoc-qcs404-objs			:= qcs404.o
@@ -61,6 +62,7 @@ obj-$(CONFIG_INTERCONNECT_QCOM_MSM8953) += qnoc-msm8953.o
 obj-$(CONFIG_INTERCONNECT_QCOM_MSM8974) += qnoc-msm8974.o
 obj-$(CONFIG_INTERCONNECT_QCOM_MSM8976) += qnoc-msm8976.o
 obj-$(CONFIG_INTERCONNECT_QCOM_MSM8996) += qnoc-msm8996.o
+obj-$(CONFIG_INTERCONNECT_QCOM_NORD) += qnoc-nord.o
 obj-$(CONFIG_INTERCONNECT_QCOM_OSM_L3) += icc-osm-l3.o
 obj-$(CONFIG_INTERCONNECT_QCOM_QCM2290) += qnoc-qcm2290.o
 obj-$(CONFIG_INTERCONNECT_QCOM_QCS404) += qnoc-qcs404.o
diff --git a/drivers/interconnect/qcom/nord.c b/drivers/interconnect/qcom/nord.c
new file mode 100644
index 000000000000..598a9c15632c
--- /dev/null
+++ b/drivers/interconnect/qcom/nord.c
@@ -0,0 +1,2682 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/interconnect.h>
+#include <linux/interconnect-provider.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <dt-bindings/interconnect/qcom,nord-rpmh.h>
+
+#include "bcm-voter.h"
+#include "icc-rpmh.h"
+
+static struct qcom_icc_node qup0_core_slave = {
+	.name = "qup0_core_slave",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qup1_core_slave = {
+	.name = "qup1_core_slave",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qup2_core_slave = {
+	.name = "qup2_core_slave",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qup3_core_slave = {
+	.name = "qup3_core_slave",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node ps_eth_0 = {
+	.name = "ps_eth_0",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node ps_eth_1 = {
+	.name = "ps_eth_1",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node ps_shs_server = {
+	.name = "ps_shs_server",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_ahb2phy0 = {
+	.name = "qhs_ahb2phy0",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_ahb2phy1 = {
+	.name = "qhs_ahb2phy1",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_ahb2phy2 = {
+	.name = "qhs_ahb2phy2",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_ahb2phy3 = {
+	.name = "qhs_ahb2phy3",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_ahb2phy_eth_0 = {
+	.name = "qhs_ahb2phy_eth_0",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_ahb2phy_eth_1 = {
+	.name = "qhs_ahb2phy_eth_1",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_camera_cfg = {
+	.name = "qhs_camera_cfg",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_clk_ctl = {
+	.name = "qhs_clk_ctl",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_crypto0_cfg = {
+	.name = "qhs_crypto0_cfg",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_crypto1_cfg = {
+	.name = "qhs_crypto1_cfg",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_crypto2_cfg = {
+	.name = "qhs_crypto2_cfg",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_display_1_cfg = {
+	.name = "qhs_display_1_cfg",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_display_cfg = {
+	.name = "qhs_display_cfg",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_dprx0 = {
+	.name = "qhs_dprx0",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_dprx1 = {
+	.name = "qhs_dprx1",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_eva_cfg = {
+	.name = "qhs_eva_cfg",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_gpuss_0_cfg = {
+	.name = "qhs_gpuss_0_cfg",
+	.channels = 1,
+	.buswidth = 8,
+};
+
+static struct qcom_icc_node qhs_gpuss_1_cfg = {
+	.name = "qhs_gpuss_1_cfg",
+	.channels = 1,
+	.buswidth = 8,
+};
+
+static struct qcom_icc_node qhs_i2c = {
+	.name = "qhs_i2c",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_imem_cfg = {
+	.name = "qhs_imem_cfg",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_mcw_pcie = {
+	.name = "qhs_mcw_pcie",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_mm_rscc = {
+	.name = "qhs_mm_rscc",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_ne_clk_ctl = {
+	.name = "qhs_ne_clk_ctl",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_nspss0_cfg = {
+	.name = "qhs_nspss0_cfg",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_nspss1_cfg = {
+	.name = "qhs_nspss1_cfg",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_nspss2_cfg = {
+	.name = "qhs_nspss2_cfg",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_nspss3_cfg = {
+	.name = "qhs_nspss3_cfg",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_nw_clk_ctl = {
+	.name = "qhs_nw_clk_ctl",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_prng = {
+	.name = "qhs_prng",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_qdss_cfg = {
+	.name = "qhs_qdss_cfg",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_qspi = {
+	.name = "qhs_qspi",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_qup0 = {
+	.name = "qhs_qup0",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_qup02 = {
+	.name = "qhs_qup02",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_qup1 = {
+	.name = "qhs_qup1",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_qup2 = {
+	.name = "qhs_qup2",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_safedma_cfg = {
+	.name = "qhs_safedma_cfg",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_sdc4 = {
+	.name = "qhs_sdc4",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_se_clk_ctl = {
+	.name = "qhs_se_clk_ctl",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_tcsr = {
+	.name = "qhs_tcsr",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_tlmm = {
+	.name = "qhs_tlmm",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_tsc_cfg = {
+	.name = "qhs_tsc_cfg",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_ufs_mem_cfg = {
+	.name = "qhs_ufs_mem_cfg",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_usb2 = {
+	.name = "qhs_usb2",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_usb3_0 = {
+	.name = "qhs_usb3_0",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_usb3_1 = {
+	.name = "qhs_usb3_1",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_venus_cfg = {
+	.name = "qhs_venus_cfg",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qss_computenoc_cfg = {
+	.name = "qss_computenoc_cfg",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qss_qtc_cfg = {
+	.name = "qss_qtc_cfg",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node xs_qdss_stm = {
+	.name = "xs_qdss_stm",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node xs_sys_tcu0_cfg = {
+	.name = "xs_sys_tcu0_cfg",
+	.channels = 1,
+	.buswidth = 8,
+};
+
+static struct qcom_icc_node xs_sys_tcu1_cfg = {
+	.name = "xs_sys_tcu1_cfg",
+	.channels = 1,
+	.buswidth = 8,
+};
+
+static struct qcom_icc_node xs_sys_tcu2_cfg = {
+	.name = "xs_sys_tcu2_cfg",
+	.channels = 1,
+	.buswidth = 8,
+};
+
+static struct qcom_icc_node qhs_aoss = {
+	.name = "qhs_aoss",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_hbcu = {
+	.name = "qhs_hbcu",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_ipa = {
+	.name = "qhs_ipa",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_ipc_router = {
+	.name = "qhs_ipc_router",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_soccp = {
+	.name = "qhs_soccp",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_tme_cfg = {
+	.name = "qhs_tme_cfg",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qss_ddrss_cfg = {
+	.name = "qss_ddrss_cfg",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qxs_imem = {
+	.name = "qxs_imem",
+	.channels = 1,
+	.buswidth = 8,
+};
+
+static struct qcom_icc_node ebi = {
+	.name = "ebi",
+	.channels = 16,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_pcie_ahb2phy_cfg = {
+	.name = "qhs_pcie_ahb2phy_cfg",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_pcie_cfg_0 = {
+	.name = "qhs_pcie_cfg_0",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_pcie_cfg_1 = {
+	.name = "qhs_pcie_cfg_1",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_pcie_cfg_2 = {
+	.name = "qhs_pcie_cfg_2",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_pcie_cfg_3 = {
+	.name = "qhs_pcie_cfg_3",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_pcie_dma_0_cfg = {
+	.name = "qhs_pcie_dma_0_cfg",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_pcie_dma_1_cfg = {
+	.name = "qhs_pcie_dma_1_cfg",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qhs_pcie_dma_2_cfg = {
+	.name = "qhs_pcie_dma_2_cfg",
+	.channels = 1,
+	.buswidth = 4,
+};
+
+static struct qcom_icc_node qxs_pcie_dma_0 = {
+	.name = "qxs_pcie_dma_0",
+	.channels = 1,
+	.buswidth = 8,
+};
+
+static struct qcom_icc_node qxs_pcie_dma_1 = {
+	.name = "qxs_pcie_dma_1",
+	.channels = 1,
+	.buswidth = 8,
+};
+
+static struct qcom_icc_node qxs_pcie_dma_2 = {
+	.name = "qxs_pcie_dma_2",
+	.channels = 1,
+	.buswidth = 8,
+};
+
+static struct qcom_icc_node xs_pcie_0 = {
+	.name = "xs_pcie_0",
+	.channels = 1,
+	.buswidth = 32,
+};
+
+static struct qcom_icc_node xs_pcie_1 = {
+	.name = "xs_pcie_1",
+	.channels = 1,
+	.buswidth = 32,
+};
+
+static struct qcom_icc_node xs_pcie_2 = {
+	.name = "xs_pcie_2",
+	.channels = 1,
+	.buswidth = 16,
+};
+
+static struct qcom_icc_node xs_pcie_3 = {
+	.name = "xs_pcie_3",
+	.channels = 1,
+	.buswidth = 8,
+};
+
+static struct qcom_icc_node qup0_core_master = {
+	.name = "qup0_core_master",
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.link_nodes = { &qup0_core_slave },
+};
+
+static struct qcom_icc_node qup1_core_master = {
+	.name = "qup1_core_master",
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.link_nodes = { &qup1_core_slave },
+};
+
+static struct qcom_icc_node qup2_core_master = {
+	.name = "qup2_core_master",
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.link_nodes = { &qup2_core_slave },
+};
+
+static struct qcom_icc_node qup3_core_master = {
+	.name = "qup3_core_master",
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.link_nodes = { &qup3_core_slave },
+};
+
+static struct qcom_icc_node llcc_mc = {
+	.name = "llcc_mc",
+	.channels = 16,
+	.buswidth = 4,
+	.num_links = 1,
+	.link_nodes = { &ebi },
+};
+
+static struct qcom_icc_node qsm_pcie_noc_cfg = {
+	.name = "qsm_pcie_noc_cfg",
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 8,
+	.link_nodes = { &qhs_pcie_ahb2phy_cfg, &qhs_pcie_cfg_0,
+			&qhs_pcie_cfg_1, &qhs_pcie_cfg_2,
+			&qhs_pcie_cfg_3, &qhs_pcie_dma_0_cfg,
+			&qhs_pcie_dma_1_cfg, &qhs_pcie_dma_2_cfg },
+};
+
+static struct qcom_icc_node qnm_cnoc_pcie_dma = {
+	.name = "qnm_cnoc_pcie_dma",
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 3,
+	.link_nodes = { &qxs_pcie_dma_0, &qxs_pcie_dma_1,
+			&qxs_pcie_dma_2 },
+};
+
+static struct qcom_icc_node qnm_hscnoc_pcie = {
+	.name = "qnm_hscnoc_pcie",
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 4,
+	.link_nodes = { &xs_pcie_0, &xs_pcie_1,
+			&xs_pcie_2, &xs_pcie_3 },
+};
+
+static struct qcom_icc_node qnm_pcie_ibnoc_dma = {
+	.name = "qnm_pcie_ibnoc_dma",
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 1,
+	.link_nodes = { &xs_pcie_0 },
+};
+
+static struct qcom_icc_node qss_pcie_noc_cfg = {
+	.name = "qss_pcie_noc_cfg",
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.link_nodes = { &qsm_pcie_noc_cfg },
+};
+
+static struct qcom_icc_node qns_pcie_dma = {
+	.name = "qns_pcie_dma",
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 1,
+	.link_nodes = { &qnm_cnoc_pcie_dma },
+};
+
+static struct qcom_icc_node qns_llcc = {
+	.name = "qns_llcc",
+	.channels = 16,
+	.buswidth = 16,
+	.num_links = 1,
+	.link_nodes = { &llcc_mc },
+};
+
+static struct qcom_icc_node qns_pcie = {
+	.name = "qns_pcie",
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 1,
+	.link_nodes = { &qnm_hscnoc_pcie },
+};
+
+static struct qcom_icc_node qns_pcie_obnoc_dma = {
+	.name = "qns_pcie_obnoc_dma",
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 1,
+	.link_nodes = { &qnm_pcie_ibnoc_dma },
+};
+
+static struct qcom_icc_node qsm_cfg = {
+	.name = "qsm_cfg",
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 56,
+	.link_nodes = { &ps_eth_0, &ps_eth_1,
+			&ps_shs_server, &qhs_ahb2phy0,
+			&qhs_ahb2phy1, &qhs_ahb2phy2,
+			&qhs_ahb2phy3, &qhs_ahb2phy_eth_0,
+			&qhs_ahb2phy_eth_1, &qhs_camera_cfg,
+			&qhs_clk_ctl, &qhs_crypto0_cfg,
+			&qhs_crypto1_cfg, &qhs_crypto2_cfg,
+			&qhs_display_1_cfg, &qhs_display_cfg,
+			&qhs_dprx0, &qhs_dprx1,
+			&qhs_eva_cfg, &qhs_gpuss_0_cfg,
+			&qhs_gpuss_1_cfg, &qhs_i2c,
+			&qhs_imem_cfg, &qhs_mcw_pcie,
+			&qhs_mm_rscc, &qhs_ne_clk_ctl,
+			&qhs_nspss0_cfg, &qhs_nspss1_cfg,
+			&qhs_nspss2_cfg, &qhs_nspss3_cfg,
+			&qhs_nw_clk_ctl, &qhs_prng,
+			&qhs_qdss_cfg, &qhs_qspi,
+			&qhs_qup0, &qhs_qup02,
+			&qhs_qup1, &qhs_qup2,
+			&qhs_safedma_cfg, &qhs_sdc4,
+			&qhs_se_clk_ctl, &qhs_tcsr,
+			&qhs_tlmm, &qhs_tsc_cfg,
+			&qhs_ufs_mem_cfg, &qhs_usb2,
+			&qhs_usb3_0, &qhs_usb3_1,
+			&qhs_venus_cfg, &qss_computenoc_cfg,
+			&qss_pcie_noc_cfg, &qss_qtc_cfg,
+			&xs_qdss_stm, &xs_sys_tcu0_cfg,
+			&xs_sys_tcu1_cfg, &xs_sys_tcu2_cfg },
+};
+
+static struct qcom_icc_node xm_gic = {
+	.name = "xm_gic",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0xa44000 },
+		.prio = 4,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_llcc },
+};
+
+static struct qcom_icc_node qss_cfg = {
+	.name = "qss_cfg",
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.link_nodes = { &qsm_cfg },
+};
+
+static struct qcom_icc_node qhm_mm_rscc = {
+	.name = "qhm_mm_rscc",
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.link_nodes = { &qss_cfg },
+};
+
+static struct qcom_icc_node qnm_hscnoc = {
+	.name = "qnm_hscnoc",
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 10,
+	.link_nodes = { &qhs_aoss, &qhs_hbcu,
+			&qhs_ipa, &qhs_ipc_router,
+			&qhs_soccp, &qhs_tme_cfg,
+			&qns_pcie_dma, &qss_cfg,
+			&qss_ddrss_cfg, &qxs_imem },
+};
+
+static struct qcom_icc_node qns_hscnoc_cnoc = {
+	.name = "qns_hscnoc_cnoc",
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 1,
+	.link_nodes = { &qnm_hscnoc },
+};
+
+static struct qcom_icc_node alm_gpu_tcu = {
+	.name = "alm_gpu_tcu",
+	.channels = 2,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 2,
+		.port_offsets = { 0x930000, 0xa45000 },
+		.prio = 1,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 2,
+	.link_nodes = { &qns_hscnoc_cnoc, &qns_llcc },
+};
+
+static struct qcom_icc_node alm_qtc = {
+	.name = "alm_qtc",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x242000 },
+		.prio = 3,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 2,
+	.link_nodes = { &qns_hscnoc_cnoc, &qns_llcc },
+};
+
+static struct qcom_icc_node alm_sys_tcu0 = {
+	.name = "alm_sys_tcu0",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0xa42000 },
+		.prio = 6,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 2,
+	.link_nodes = { &qns_hscnoc_cnoc, &qns_llcc },
+};
+
+static struct qcom_icc_node alm_sys_tcu1 = {
+	.name = "alm_sys_tcu1",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x81c000 },
+		.prio = 6,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 2,
+	.link_nodes = { &qns_hscnoc_cnoc, &qns_llcc },
+};
+
+static struct qcom_icc_node alm_sys_tcu2 = {
+	.name = "alm_sys_tcu2",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x30000 },
+		.prio = 6,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 2,
+	.link_nodes = { &qns_hscnoc_cnoc, &qns_llcc },
+};
+
+static struct qcom_icc_node chm_apps = {
+	.name = "chm_apps",
+	.channels = 6,
+	.buswidth = 32,
+	.num_links = 3,
+	.link_nodes = { &qns_hscnoc_cnoc, &qns_llcc,
+			&qns_pcie },
+};
+
+static struct qcom_icc_node qnm_aggre_north = {
+	.name = "qnm_aggre_north",
+	.channels = 1,
+	.buswidth = 16,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x935000 },
+		.prio = 0,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 0,
+	},
+	.num_links = 3,
+	.link_nodes = { &qns_hscnoc_cnoc, &qns_llcc,
+			&qns_pcie },
+};
+
+static struct qcom_icc_node qnm_aggre_south = {
+	.name = "qnm_aggre_south",
+	.channels = 1,
+	.buswidth = 16,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x31000 },
+		.prio = 0,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 0,
+	},
+	.num_links = 3,
+	.link_nodes = { &qns_hscnoc_cnoc, &qns_llcc,
+			&qns_pcie },
+};
+
+static struct qcom_icc_node qnm_gpu0 = {
+	.name = "qnm_gpu0",
+	.channels = 4,
+	.buswidth = 32,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 4,
+		.port_offsets = { 0x931000, 0x932000, 0x933000, 0x934000 },
+		.prio = 0,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 3,
+	.link_nodes = { &qns_hscnoc_cnoc, &qns_llcc,
+			&qns_pcie },
+};
+
+static struct qcom_icc_node qnm_gpu1 = {
+	.name = "qnm_gpu1",
+	.channels = 2,
+	.buswidth = 32,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 2,
+		.port_offsets = { 0xa40000, 0xa41000 },
+		.prio = 0,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 3,
+	.link_nodes = { &qns_hscnoc_cnoc, &qns_llcc,
+			&qns_pcie },
+};
+
+static struct qcom_icc_node qnm_hpass_adas_hscnoc = {
+	.name = "qnm_hpass_adas_hscnoc",
+	.channels = 2,
+	.buswidth = 32,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 2,
+		.port_offsets = { 0x240000, 0x245000 },
+		.prio = 0,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 0,
+	},
+	.num_links = 3,
+	.link_nodes = { &qns_hscnoc_cnoc, &qns_llcc,
+			&qns_pcie },
+};
+
+static struct qcom_icc_node qnm_hpass_audio_hscnoc = {
+	.name = "qnm_hpass_audio_hscnoc",
+	.channels = 1,
+	.buswidth = 32,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x241000 },
+		.prio = 3,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 0,
+	},
+	.num_links = 3,
+	.link_nodes = { &qns_hscnoc_cnoc, &qns_llcc,
+			&qns_pcie },
+};
+
+static struct qcom_icc_node qnm_mnoc_hf = {
+	.name = "qnm_mnoc_hf",
+	.channels = 2,
+	.buswidth = 32,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 2,
+		.port_offsets = { 0x81a000, 0x81d000 },
+		.prio = 0,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 0,
+	},
+	.num_links = 3,
+	.link_nodes = { &qns_hscnoc_cnoc, &qns_llcc,
+			&qns_pcie },
+};
+
+static struct qcom_icc_node qnm_mnoc_sf = {
+	.name = "qnm_mnoc_sf",
+	.channels = 2,
+	.buswidth = 32,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 2,
+		.port_offsets = { 0x81b000, 0x81e000 },
+		.prio = 0,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 0,
+	},
+	.num_links = 3,
+	.link_nodes = { &qns_hscnoc_cnoc, &qns_llcc,
+			&qns_pcie },
+};
+
+static struct qcom_icc_node qnm_nsp0_hscnoc = {
+	.name = "qnm_nsp0_hscnoc",
+	.channels = 2,
+	.buswidth = 32,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 2,
+		.port_offsets = { 0x32000, 0x33000 },
+		.prio = 0,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 3,
+	.link_nodes = { &qns_hscnoc_cnoc, &qns_llcc,
+			&qns_pcie },
+};
+
+static struct qcom_icc_node qnm_nsp1_hscnoc = {
+	.name = "qnm_nsp1_hscnoc",
+	.channels = 2,
+	.buswidth = 32,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 2,
+		.port_offsets = { 0x34000, 0x35000 },
+		.prio = 0,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 3,
+	.link_nodes = { &qns_hscnoc_cnoc, &qns_llcc,
+			&qns_pcie },
+};
+
+static struct qcom_icc_node qnm_nsp2_hscnoc = {
+	.name = "qnm_nsp2_hscnoc",
+	.channels = 2,
+	.buswidth = 32,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 2,
+		.port_offsets = { 0x36000, 0x37000 },
+		.prio = 0,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 3,
+	.link_nodes = { &qns_hscnoc_cnoc, &qns_llcc,
+			&qns_pcie },
+};
+
+static struct qcom_icc_node qnm_nsp3_hscnoc = {
+	.name = "qnm_nsp3_hscnoc",
+	.channels = 2,
+	.buswidth = 32,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 2,
+		.port_offsets = { 0x38000, 0x39000 },
+		.prio = 0,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 3,
+	.link_nodes = { &qns_hscnoc_cnoc, &qns_llcc,
+			&qns_pcie },
+};
+
+static struct qcom_icc_node qnm_pcie = {
+	.name = "qnm_pcie",
+	.channels = 1,
+	.buswidth = 64,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x244000 },
+		.prio = 2,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 2,
+	.link_nodes = { &qns_hscnoc_cnoc, &qns_llcc },
+};
+
+static struct qcom_icc_node qnm_sailss_md0_hscnoc = {
+	.name = "qnm_sailss_md0_hscnoc",
+	.channels = 1,
+	.buswidth = 16,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x243000 },
+		.prio = 2,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 3,
+	.link_nodes = { &qns_hscnoc_cnoc, &qns_llcc,
+			&qns_pcie },
+};
+
+static struct qcom_icc_node qnm_snoc_sf = {
+	.name = "qnm_snoc_sf",
+	.channels = 1,
+	.buswidth = 64,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0xa43000 },
+		.prio = 0,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 0,
+	},
+	.num_links = 3,
+	.link_nodes = { &qns_hscnoc_cnoc, &qns_llcc,
+			&qns_pcie },
+};
+
+static struct qcom_icc_node qns_a1noc_hscnoc = {
+	.name = "qns_a1noc_hscnoc",
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 1,
+	.link_nodes = { &qnm_aggre_north },
+};
+
+static struct qcom_icc_node qns_a2noc_hscnoc = {
+	.name = "qns_a2noc_hscnoc",
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 1,
+	.link_nodes = { &qnm_aggre_south },
+};
+
+static struct qcom_icc_node qns_hpass_agnoc_audio = {
+	.name = "qns_hpass_agnoc_audio",
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 1,
+	.link_nodes = { &qnm_hpass_audio_hscnoc },
+};
+
+static struct qcom_icc_node qns_mem_noc_hf = {
+	.name = "qns_mem_noc_hf",
+	.channels = 2,
+	.buswidth = 32,
+	.num_links = 1,
+	.link_nodes = { &qnm_mnoc_hf },
+};
+
+static struct qcom_icc_node qns_mem_noc_sf = {
+	.name = "qns_mem_noc_sf",
+	.channels = 2,
+	.buswidth = 32,
+	.num_links = 1,
+	.link_nodes = { &qnm_mnoc_sf },
+};
+
+static struct qcom_icc_node qns_nsp0_hsc_noc = {
+	.name = "qns_nsp0_hsc_noc",
+	.channels = 2,
+	.buswidth = 32,
+	.num_links = 1,
+	.link_nodes = { &qnm_nsp0_hscnoc },
+};
+
+static struct qcom_icc_node qns_nsp1_hsc_noc = {
+	.name = "qns_nsp1_hsc_noc",
+	.channels = 2,
+	.buswidth = 32,
+	.num_links = 1,
+	.link_nodes = { &qnm_nsp1_hscnoc },
+};
+
+static struct qcom_icc_node qns_nsp2_hsc_noc = {
+	.name = "qns_nsp2_hsc_noc",
+	.channels = 2,
+	.buswidth = 32,
+	.num_links = 1,
+	.link_nodes = { &qnm_nsp2_hscnoc },
+};
+
+static struct qcom_icc_node qns_nsp3_hsc_noc = {
+	.name = "qns_nsp3_hsc_noc",
+	.channels = 2,
+	.buswidth = 32,
+	.num_links = 1,
+	.link_nodes = { &qnm_nsp3_hscnoc },
+};
+
+static struct qcom_icc_node qns_pcie_hscnoc = {
+	.name = "qns_pcie_hscnoc",
+	.channels = 1,
+	.buswidth = 64,
+	.num_links = 1,
+	.link_nodes = { &qnm_pcie },
+};
+
+static struct qcom_icc_node qns_hscnoc_sf = {
+	.name = "qns_hscnoc_sf",
+	.channels = 1,
+	.buswidth = 64,
+	.num_links = 1,
+	.link_nodes = { &qnm_snoc_sf },
+};
+
+static struct qcom_icc_node qhm_qup2 = {
+	.name = "qhm_qup2",
+	.channels = 1,
+	.buswidth = 4,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x1b000 },
+		.prio = 2,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_a1noc_hscnoc },
+};
+
+static struct qcom_icc_node qxm_crypto_0 = {
+	.name = "qxm_crypto_0",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x1c000 },
+		.prio = 2,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_a1noc_hscnoc },
+};
+
+static struct qcom_icc_node qxm_crypto_1 = {
+	.name = "qxm_crypto_1",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x1d000 },
+		.prio = 2,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_a1noc_hscnoc },
+};
+
+static struct qcom_icc_node qxm_crypto_2 = {
+	.name = "qxm_crypto_2",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x1e000 },
+		.prio = 2,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_a1noc_hscnoc },
+};
+
+static struct qcom_icc_node xm_sdc4 = {
+	.name = "xm_sdc4",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x16000 },
+		.prio = 2,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_a1noc_hscnoc },
+};
+
+static struct qcom_icc_node xm_ufs_mem = {
+	.name = "xm_ufs_mem",
+	.channels = 1,
+	.buswidth = 16,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x17000 },
+		.prio = 2,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_a1noc_hscnoc },
+};
+
+static struct qcom_icc_node xm_usb2 = {
+	.name = "xm_usb2",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x19000 },
+		.prio = 2,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_a1noc_hscnoc },
+};
+
+static struct qcom_icc_node xm_usb3_0 = {
+	.name = "xm_usb3_0",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x18000 },
+		.prio = 2,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_a1noc_hscnoc },
+};
+
+static struct qcom_icc_node xm_usb3_1 = {
+	.name = "xm_usb3_1",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x1a000 },
+		.prio = 2,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_a1noc_hscnoc },
+};
+
+static struct qcom_icc_node qhm_qup0 = {
+	.name = "qhm_qup0",
+	.channels = 1,
+	.buswidth = 4,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x13000 },
+		.prio = 2,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_a2noc_hscnoc },
+};
+
+static struct qcom_icc_node qhm_qup1 = {
+	.name = "qhm_qup1",
+	.channels = 1,
+	.buswidth = 4,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x14000 },
+		.prio = 2,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_a2noc_hscnoc },
+};
+
+static struct qcom_icc_node xm_emac_0 = {
+	.name = "xm_emac_0",
+	.channels = 1,
+	.buswidth = 16,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x16000 },
+		.prio = 2,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_a2noc_hscnoc },
+};
+
+static struct qcom_icc_node xm_emac_1 = {
+	.name = "xm_emac_1",
+	.channels = 1,
+	.buswidth = 16,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x17000 },
+		.prio = 2,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_a2noc_hscnoc },
+};
+
+static struct qcom_icc_node qnm_hpass_dsp0 = {
+	.name = "qnm_hpass_dsp0",
+	.channels = 2,
+	.buswidth = 32,
+	.num_links = 1,
+	.link_nodes = { &qns_hpass_agnoc_audio },
+};
+
+static struct qcom_icc_node qnm_hpass_dsp1 = {
+	.name = "qnm_hpass_dsp1",
+	.channels = 2,
+	.buswidth = 32,
+	.num_links = 1,
+	.link_nodes = { &qns_hpass_agnoc_audio },
+};
+
+static struct qcom_icc_node qnm_hpass_dsp2 = {
+	.name = "qnm_hpass_dsp2",
+	.channels = 2,
+	.buswidth = 32,
+	.num_links = 1,
+	.link_nodes = { &qns_hpass_agnoc_audio },
+};
+
+static struct qcom_icc_node qnm_camnoc_hf = {
+	.name = "qnm_camnoc_hf",
+	.channels = 2,
+	.buswidth = 32,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 2,
+		.port_offsets = { 0x57000, 0x58000 },
+		.prio = 0,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 0,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_mem_noc_hf },
+};
+
+static struct qcom_icc_node qnm_camnoc_nrt_icp_sf = {
+	.name = "qnm_camnoc_nrt_icp_sf",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x1a000 },
+		.prio = 4,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_mem_noc_sf },
+};
+
+static struct qcom_icc_node qnm_camnoc_rt_cdm_sf = {
+	.name = "qnm_camnoc_rt_cdm_sf",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x5b000 },
+		.prio = 2,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_mem_noc_sf },
+};
+
+static struct qcom_icc_node qnm_camnoc_sf = {
+	.name = "qnm_camnoc_sf",
+	.channels = 2,
+	.buswidth = 32,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 2,
+		.port_offsets = { 0x1b000, 0x1c000 },
+		.prio = 0,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 0,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_mem_noc_sf },
+};
+
+static struct qcom_icc_node qnm_dprx0 = {
+	.name = "qnm_dprx0",
+	.channels = 1,
+	.buswidth = 32,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x5c000 },
+		.prio = 0,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 0,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_mem_noc_hf },
+};
+
+static struct qcom_icc_node qnm_dprx1 = {
+	.name = "qnm_dprx1",
+	.channels = 1,
+	.buswidth = 32,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x5d000 },
+		.prio = 0,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 0,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_mem_noc_hf },
+};
+
+static struct qcom_icc_node qnm_mdp0 = {
+	.name = "qnm_mdp0",
+	.channels = 2,
+	.buswidth = 32,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 2,
+		.port_offsets = { 0x59000, 0x5a000 },
+		.prio = 0,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 0,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_mem_noc_hf },
+};
+
+static struct qcom_icc_node qnm_mdp1 = {
+	.name = "qnm_mdp1",
+	.channels = 2,
+	.buswidth = 32,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 2,
+		.port_offsets = { 0x5e000, 0x5f000 },
+		.prio = 0,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 0,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_mem_noc_hf },
+};
+
+static struct qcom_icc_node qnm_video_cv_cpu = {
+	.name = "qnm_video_cv_cpu",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x21000 },
+		.prio = 4,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_mem_noc_sf },
+};
+
+static struct qcom_icc_node qnm_video_eva = {
+	.name = "qnm_video_eva",
+	.channels = 2,
+	.buswidth = 32,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 2,
+		.port_offsets = { 0x22000, 0x23000 },
+		.prio = 0,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 0,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_mem_noc_sf },
+};
+
+static struct qcom_icc_node qnm_video_mvp0 = {
+	.name = "qnm_video_mvp0",
+	.channels = 2,
+	.buswidth = 32,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 2,
+		.port_offsets = { 0x1d000, 0x1e000 },
+		.prio = 0,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 0,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_mem_noc_sf },
+};
+
+static struct qcom_icc_node qnm_video_mvp1 = {
+	.name = "qnm_video_mvp1",
+	.channels = 2,
+	.buswidth = 32,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 2,
+		.port_offsets = { 0x1f000, 0x20000 },
+		.prio = 0,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 0,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_mem_noc_sf },
+};
+
+static struct qcom_icc_node qnm_video_v_cpu = {
+	.name = "qnm_video_v_cpu",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x24000 },
+		.prio = 4,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_mem_noc_sf },
+};
+
+static struct qcom_icc_node qnm_nsp_data00 = {
+	.name = "qnm_nsp_data00",
+	.channels = 2,
+	.buswidth = 32,
+	.num_links = 1,
+	.link_nodes = { &qns_nsp0_hsc_noc },
+};
+
+static struct qcom_icc_node qnm_nsp_data01 = {
+	.name = "qnm_nsp_data01",
+	.channels = 2,
+	.buswidth = 32,
+	.num_links = 1,
+	.link_nodes = { &qns_nsp1_hsc_noc },
+};
+
+static struct qcom_icc_node qnm_nsp_data02 = {
+	.name = "qnm_nsp_data02",
+	.channels = 2,
+	.buswidth = 32,
+	.num_links = 1,
+	.link_nodes = { &qns_nsp2_hsc_noc },
+};
+
+static struct qcom_icc_node qnm_nsp_data03 = {
+	.name = "qnm_nsp_data03",
+	.channels = 2,
+	.buswidth = 32,
+	.num_links = 1,
+	.link_nodes = { &qns_nsp3_hsc_noc },
+};
+
+static struct qcom_icc_node qxm_pcie_dma_0 = {
+	.name = "qxm_pcie_dma_0",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x49000 },
+		.prio = 0,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 0,
+	},
+	.num_links = 2,
+	.link_nodes = { &qns_pcie_hscnoc, &qns_pcie_obnoc_dma },
+};
+
+static struct qcom_icc_node qxm_pcie_dma_1 = {
+	.name = "qxm_pcie_dma_1",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x4a000 },
+		.prio = 0,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 0,
+	},
+	.num_links = 2,
+	.link_nodes = { &qns_pcie_hscnoc, &qns_pcie_obnoc_dma },
+};
+
+static struct qcom_icc_node qxm_pcie_dma_2 = {
+	.name = "qxm_pcie_dma_2",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x4b000 },
+		.prio = 0,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 0,
+	},
+	.num_links = 2,
+	.link_nodes = { &qns_pcie_hscnoc, &qns_pcie_obnoc_dma },
+};
+
+static struct qcom_icc_node xm_pcie_0 = {
+	.name = "xm_pcie_0",
+	.channels = 1,
+	.buswidth = 64,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x18000 },
+		.prio = 2,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_pcie_hscnoc },
+};
+
+static struct qcom_icc_node xm_pcie_1 = {
+	.name = "xm_pcie_1",
+	.channels = 1,
+	.buswidth = 32,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x19000 },
+		.prio = 2,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_pcie_hscnoc },
+};
+
+static struct qcom_icc_node xm_pcie_2 = {
+	.name = "xm_pcie_2",
+	.channels = 1,
+	.buswidth = 16,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x1a000 },
+		.prio = 2,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_pcie_hscnoc },
+};
+
+static struct qcom_icc_node xm_pcie_3 = {
+	.name = "xm_pcie_3",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x1b000 },
+		.prio = 2,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_pcie_hscnoc },
+};
+
+static struct qcom_icc_node qnm_aggre1_noc = {
+	.name = "qnm_aggre1_noc",
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 1,
+	.link_nodes = { &qns_hscnoc_sf },
+};
+
+static struct qcom_icc_node qnm_aggre2_noc = {
+	.name = "qnm_aggre2_noc",
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 1,
+	.link_nodes = { &qns_hscnoc_sf },
+};
+
+static struct qcom_icc_node qnm_cnoc_data = {
+	.name = "qnm_cnoc_data",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x1a000 },
+		.prio = 2,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_hscnoc_sf },
+};
+
+static struct qcom_icc_node qnm_nsi_noc = {
+	.name = "qnm_nsi_noc",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x19000 },
+		.prio = 2,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_hscnoc_sf },
+};
+
+static struct qcom_icc_node qnm_safe_dma = {
+	.name = "qnm_safe_dma",
+	.channels = 1,
+	.buswidth = 64,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x1b000 },
+		.prio = 0,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 0,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_hscnoc_sf },
+};
+
+static struct qcom_icc_node qns_a1noc_snoc = {
+	.name = "qns_a1noc_snoc",
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 1,
+	.link_nodes = { &qnm_aggre1_noc },
+};
+
+static struct qcom_icc_node qns_a2noc_snoc = {
+	.name = "qns_a2noc_snoc",
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 1,
+	.link_nodes = { &qnm_aggre2_noc },
+};
+
+static struct qcom_icc_node qhm_qspi = {
+	.name = "qhm_qspi",
+	.channels = 1,
+	.buswidth = 4,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x18000 },
+		.prio = 2,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_a1noc_snoc },
+};
+
+static struct qcom_icc_node qnm_sailss_md1 = {
+	.name = "qnm_sailss_md1",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x16000 },
+		.prio = 2,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_a1noc_snoc },
+};
+
+static struct qcom_icc_node qxm_qup02 = {
+	.name = "qxm_qup02",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x17000 },
+		.prio = 2,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_a1noc_snoc },
+};
+
+static struct qcom_icc_node qxm_ipa = {
+	.name = "qxm_ipa",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x13000 },
+		.prio = 2,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_a2noc_snoc },
+};
+
+static struct qcom_icc_node qxm_soccp = {
+	.name = "qxm_soccp",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x16000 },
+		.prio = 2,
+		.urg_fwd = 1,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_a2noc_snoc },
+};
+
+static struct qcom_icc_node xm_qdss_etr_0 = {
+	.name = "xm_qdss_etr_0",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x14000 },
+		.prio = 2,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_a2noc_snoc },
+};
+
+static struct qcom_icc_node xm_qdss_etr_1 = {
+	.name = "xm_qdss_etr_1",
+	.channels = 1,
+	.buswidth = 8,
+	.qosbox = &(const struct qcom_icc_qosbox) {
+		.num_ports = 1,
+		.port_offsets = { 0x15000 },
+		.prio = 2,
+		.urg_fwd = 0,
+		.prio_fwd_disable = 1,
+	},
+	.num_links = 1,
+	.link_nodes = { &qns_a2noc_snoc },
+};
+
+static struct qcom_icc_bcm bcm_c0n0 = {
+	.name = "C0N0",
+	.enable_mask = BIT(0),
+	.num_nodes = 2,
+	.nodes = { &qnm_nsp_data00, &qns_nsp0_hsc_noc },
+};
+
+static struct qcom_icc_bcm bcm_c1n0 = {
+	.name = "C1N0",
+	.enable_mask = BIT(0),
+	.num_nodes = 2,
+	.nodes = { &qnm_nsp_data01, &qns_nsp1_hsc_noc },
+};
+
+static struct qcom_icc_bcm bcm_c2n0 = {
+	.name = "C2N0",
+	.enable_mask = BIT(0),
+	.num_nodes = 2,
+	.nodes = { &qnm_nsp_data02, &qns_nsp2_hsc_noc },
+};
+
+static struct qcom_icc_bcm bcm_c3n0 = {
+	.name = "C3N0",
+	.enable_mask = BIT(0),
+	.num_nodes = 2,
+	.nodes = { &qnm_nsp_data03, &qns_nsp3_hsc_noc },
+};
+
+static struct qcom_icc_bcm bcm_ce0 = {
+	.name = "CE0",
+	.num_nodes = 1,
+	.nodes = { &qxm_crypto_0 },
+};
+
+static struct qcom_icc_bcm bcm_ce1 = {
+	.name = "CE1",
+	.num_nodes = 1,
+	.nodes = { &qxm_crypto_1 },
+};
+
+static struct qcom_icc_bcm bcm_ce2 = {
+	.name = "CE2",
+	.num_nodes = 1,
+	.nodes = { &qxm_crypto_2 },
+};
+
+static struct qcom_icc_bcm bcm_cn0 = {
+	.name = "CN0",
+	.keepalive = true,
+	.enable_mask = BIT(0),
+	.num_nodes = 6,
+	.nodes = { &qsm_cfg, &qhm_mm_rscc,
+		   &qnm_hscnoc, &qnm_cnoc_pcie_dma,
+		   &qnm_hscnoc_pcie, &qnm_pcie_ibnoc_dma },
+};
+
+static struct qcom_icc_bcm bcm_cn1 = {
+	.name = "CN1",
+	.num_nodes = 2,
+	.nodes = { &qhs_display_1_cfg, &qhs_display_cfg },
+};
+
+static struct qcom_icc_bcm bcm_mc0 = {
+	.name = "MC0",
+	.keepalive = true,
+	.num_nodes = 1,
+	.nodes = { &ebi },
+};
+
+static struct qcom_icc_bcm bcm_mm0 = {
+	.name = "MM0",
+	.num_nodes = 1,
+	.nodes = { &qns_mem_noc_hf },
+};
+
+static struct qcom_icc_bcm bcm_mm1 = {
+	.name = "MM1",
+	.enable_mask = BIT(0),
+	.num_nodes = 14,
+	.nodes = { &qnm_camnoc_hf, &qnm_camnoc_nrt_icp_sf,
+		   &qnm_camnoc_rt_cdm_sf, &qnm_camnoc_sf,
+		   &qnm_dprx0, &qnm_dprx1,
+		   &qnm_mdp0, &qnm_mdp1,
+		   &qnm_video_cv_cpu, &qnm_video_eva,
+		   &qnm_video_mvp0, &qnm_video_mvp1,
+		   &qnm_video_v_cpu, &qns_mem_noc_sf },
+};
+
+static struct qcom_icc_bcm bcm_qup0 = {
+	.name = "QUP0",
+	.vote_scale = 1,
+	.keepalive = true,
+	.num_nodes = 1,
+	.nodes = { &qup0_core_slave },
+};
+
+static struct qcom_icc_bcm bcm_qup1 = {
+	.name = "QUP1",
+	.vote_scale = 1,
+	.keepalive = true,
+	.num_nodes = 1,
+	.nodes = { &qup1_core_slave },
+};
+
+static struct qcom_icc_bcm bcm_qup2 = {
+	.name = "QUP2",
+	.vote_scale = 1,
+	.keepalive = true,
+	.num_nodes = 1,
+	.nodes = { &qup2_core_slave },
+};
+
+static struct qcom_icc_bcm bcm_qup3 = {
+	.name = "QUP3",
+	.vote_scale = 1,
+	.keepalive = true,
+	.num_nodes = 1,
+	.nodes = { &qup3_core_slave },
+};
+
+static struct qcom_icc_bcm bcm_sh0 = {
+	.name = "SH0",
+	.keepalive = true,
+	.num_nodes = 1,
+	.nodes = { &qns_llcc },
+};
+
+static struct qcom_icc_bcm bcm_sh1 = {
+	.name = "SH1",
+	.enable_mask = BIT(0),
+	.num_nodes = 24,
+	.nodes = { &alm_gpu_tcu, &alm_qtc,
+		   &alm_sys_tcu0, &alm_sys_tcu1,
+		   &alm_sys_tcu2, &chm_apps,
+		   &qnm_aggre_north, &qnm_aggre_south,
+		   &qnm_gpu0, &qnm_gpu1,
+		   &qnm_hpass_adas_hscnoc, &qnm_hpass_audio_hscnoc,
+		   &qnm_mnoc_hf, &qnm_mnoc_sf,
+		   &qnm_nsp0_hscnoc, &qnm_nsp1_hscnoc,
+		   &qnm_nsp2_hscnoc, &qnm_nsp3_hscnoc,
+		   &qnm_pcie, &qnm_sailss_md0_hscnoc,
+		   &qnm_snoc_sf, &xm_gic,
+		   &qns_hscnoc_cnoc, &qns_pcie },
+};
+
+static struct qcom_icc_bcm bcm_sn0 = {
+	.name = "SN0",
+	.keepalive = true,
+	.num_nodes = 1,
+	.nodes = { &qns_hscnoc_sf },
+};
+
+static struct qcom_icc_bcm bcm_sn1 = {
+	.name = "SN1",
+	.enable_mask = BIT(0),
+	.num_nodes = 14,
+	.nodes = { &qns_a1noc_hscnoc, &qns_a2noc_hscnoc,
+		   &qxm_pcie_dma_0, &qxm_pcie_dma_1,
+		   &qxm_pcie_dma_2, &xm_pcie_0,
+		   &xm_pcie_1, &xm_pcie_2,
+		   &xm_pcie_3, &qns_pcie_hscnoc,
+		   &qns_pcie_obnoc_dma, &qnm_cnoc_data,
+		   &qnm_nsi_noc, &qnm_safe_dma },
+};
+
+static struct qcom_icc_bcm bcm_sn2 = {
+	.name = "SN2",
+	.num_nodes = 1,
+	.nodes = { &qnm_aggre1_noc },
+};
+
+static struct qcom_icc_bcm bcm_sn3 = {
+	.name = "SN3",
+	.num_nodes = 1,
+	.nodes = { &qnm_aggre2_noc },
+};
+
+static struct qcom_icc_node * const aggre1_noc_nodes[] = {
+	[MASTER_QSPI_0] = &qhm_qspi,
+	[MASTER_SAILSS_MD1] = &qnm_sailss_md1,
+	[MASTER_QUP_3] = &qxm_qup02,
+	[SLAVE_A1NOC_SNOC] = &qns_a1noc_snoc,
+};
+
+static const struct regmap_config nord_aggre1_noc_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x1c400,
+	.fast_io = true,
+};
+
+static const struct qcom_icc_desc nord_aggre1_noc = {
+	.config = &nord_aggre1_noc_regmap_config,
+	.nodes = aggre1_noc_nodes,
+	.num_nodes = ARRAY_SIZE(aggre1_noc_nodes),
+};
+
+static struct qcom_icc_bcm * const aggre1_noc_tile_bcms[] = {
+	&bcm_ce0,
+	&bcm_ce1,
+	&bcm_ce2,
+	&bcm_sn1,
+};
+
+static struct qcom_icc_node * const aggre1_noc_tile_nodes[] = {
+	[MASTER_QUP_2] = &qhm_qup2,
+	[MASTER_CRYPTO_CORE0] = &qxm_crypto_0,
+	[MASTER_CRYPTO_CORE1] = &qxm_crypto_1,
+	[MASTER_CRYPTO_CORE2] = &qxm_crypto_2,
+	[MASTER_SDCC_4] = &xm_sdc4,
+	[MASTER_UFS_MEM] = &xm_ufs_mem,
+	[MASTER_USB2] = &xm_usb2,
+	[MASTER_USB3_0] = &xm_usb3_0,
+	[MASTER_USB3_1] = &xm_usb3_1,
+	[SLAVE_A1NOC_HSCNOC] = &qns_a1noc_hscnoc,
+};
+
+static const struct regmap_config nord_aggre1_noc_tile_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x23400,
+	.fast_io = true,
+};
+
+static const struct qcom_icc_desc nord_aggre1_noc_tile = {
+	.config = &nord_aggre1_noc_tile_regmap_config,
+	.nodes = aggre1_noc_tile_nodes,
+	.num_nodes = ARRAY_SIZE(aggre1_noc_tile_nodes),
+	.bcms = aggre1_noc_tile_bcms,
+	.num_bcms = ARRAY_SIZE(aggre1_noc_tile_bcms),
+};
+
+static struct qcom_icc_node * const aggre2_noc_nodes[] = {
+	[MASTER_IPA] = &qxm_ipa,
+	[MASTER_SOCCP_AGGR_NOC] = &qxm_soccp,
+	[MASTER_QDSS_ETR] = &xm_qdss_etr_0,
+	[MASTER_QDSS_ETR_1] = &xm_qdss_etr_1,
+	[SLAVE_A2NOC_SNOC] = &qns_a2noc_snoc,
+};
+
+static const struct regmap_config nord_aggre2_noc_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x1b400,
+	.fast_io = true,
+};
+
+static const struct qcom_icc_desc nord_aggre2_noc = {
+	.config = &nord_aggre2_noc_regmap_config,
+	.nodes = aggre2_noc_nodes,
+	.num_nodes = ARRAY_SIZE(aggre2_noc_nodes),
+};
+
+static struct qcom_icc_bcm * const aggre2_noc_tile_bcms[] = {
+	&bcm_sn1,
+};
+
+static struct qcom_icc_node * const aggre2_noc_tile_nodes[] = {
+	[MASTER_QUP_0] = &qhm_qup0,
+	[MASTER_QUP_1] = &qhm_qup1,
+	[MASTER_EMAC_0] = &xm_emac_0,
+	[MASTER_EMAC_1] = &xm_emac_1,
+	[SLAVE_A2NOC_HSCNOC] = &qns_a2noc_hscnoc,
+};
+
+static const struct regmap_config nord_aggre2_noc_tile_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x1b400,
+	.fast_io = true,
+};
+
+static const struct qcom_icc_desc nord_aggre2_noc_tile = {
+	.config = &nord_aggre2_noc_tile_regmap_config,
+	.nodes = aggre2_noc_tile_nodes,
+	.num_nodes = ARRAY_SIZE(aggre2_noc_tile_nodes),
+	.bcms = aggre2_noc_tile_bcms,
+	.num_bcms = ARRAY_SIZE(aggre2_noc_tile_bcms),
+};
+
+static struct qcom_icc_bcm * const clk_virt_bcms[] = {
+	&bcm_qup0,
+	&bcm_qup1,
+	&bcm_qup2,
+	&bcm_qup3,
+};
+
+static struct qcom_icc_node * const clk_virt_nodes[] = {
+	[MASTER_QUP_CORE_0] = &qup0_core_master,
+	[MASTER_QUP_CORE_1] = &qup1_core_master,
+	[MASTER_QUP_CORE_2] = &qup2_core_master,
+	[MASTER_QUP_CORE_3] = &qup3_core_master,
+	[SLAVE_QUP_CORE_0] = &qup0_core_slave,
+	[SLAVE_QUP_CORE_1] = &qup1_core_slave,
+	[SLAVE_QUP_CORE_2] = &qup2_core_slave,
+	[SLAVE_QUP_CORE_3] = &qup3_core_slave,
+};
+
+static const struct qcom_icc_desc nord_clk_virt = {
+	.nodes = clk_virt_nodes,
+	.num_nodes = ARRAY_SIZE(clk_virt_nodes),
+	.bcms = clk_virt_bcms,
+	.num_bcms = ARRAY_SIZE(clk_virt_bcms),
+};
+
+static struct qcom_icc_bcm * const cnoc_cfg_bcms[] = {
+	&bcm_cn0,
+	&bcm_cn1,
+};
+
+static struct qcom_icc_node * const cnoc_cfg_nodes[] = {
+	[MASTER_CNOC_CFG] = &qsm_cfg,
+	[SLAVE_PS_ETH_0] = &ps_eth_0,
+	[SLAVE_PS_ETH_1] = &ps_eth_1,
+	[SLAVE_SHS_SERVER] = &ps_shs_server,
+	[SLAVE_AHB2PHY_0] = &qhs_ahb2phy0,
+	[SLAVE_AHB2PHY_1] = &qhs_ahb2phy1,
+	[SLAVE_AHB2PHY_2] = &qhs_ahb2phy2,
+	[SLAVE_AHB2PHY_3] = &qhs_ahb2phy3,
+	[SLAVE_AHB2PHY_ETH_0] = &qhs_ahb2phy_eth_0,
+	[SLAVE_AHB2PHY_ETH_1] = &qhs_ahb2phy_eth_1,
+	[SLAVE_CAMERA_CFG] = &qhs_camera_cfg,
+	[SLAVE_CLK_CTL] = &qhs_clk_ctl,
+	[SLAVE_CRYPTO_0_CFG] = &qhs_crypto0_cfg,
+	[SLAVE_CRYPTO_1_CFG] = &qhs_crypto1_cfg,
+	[SLAVE_CRYPTO_2_CFG] = &qhs_crypto2_cfg,
+	[SLAVE_DISPLAY_1_CFG] = &qhs_display_1_cfg,
+	[SLAVE_DISPLAY_CFG] = &qhs_display_cfg,
+	[SLAVE_DPRX0] = &qhs_dprx0,
+	[SLAVE_DPRX1] = &qhs_dprx1,
+	[SLAVE_EVA_CFG] = &qhs_eva_cfg,
+	[SLAVE_GFX3D_CFG] = &qhs_gpuss_0_cfg,
+	[SLAVE_GFX3D_1_CFG] = &qhs_gpuss_1_cfg,
+	[SLAVE_I2C] = &qhs_i2c,
+	[SLAVE_IMEM_CFG] = &qhs_imem_cfg,
+	[SLAVE_MCW_PCIE] = &qhs_mcw_pcie,
+	[SLAVE_MM_RSCC] = &qhs_mm_rscc,
+	[SLAVE_NE_CLK_CTL] = &qhs_ne_clk_ctl,
+	[SLAVE_NSPSS0_CFG] = &qhs_nspss0_cfg,
+	[SLAVE_NSPSS1_CFG] = &qhs_nspss1_cfg,
+	[SLAVE_NSPSS2_CFG] = &qhs_nspss2_cfg,
+	[SLAVE_NSPSS3_CFG] = &qhs_nspss3_cfg,
+	[SLAVE_NW_CLK_CTL] = &qhs_nw_clk_ctl,
+	[SLAVE_PRNG] = &qhs_prng,
+	[SLAVE_QDSS_CFG] = &qhs_qdss_cfg,
+	[SLAVE_QSPI_0] = &qhs_qspi,
+	[SLAVE_QUP_0] = &qhs_qup0,
+	[SLAVE_QUP_3] = &qhs_qup02,
+	[SLAVE_QUP_1] = &qhs_qup1,
+	[SLAVE_QUP_2] = &qhs_qup2,
+	[SLAVE_SAFEDMA_CFG] = &qhs_safedma_cfg,
+	[SLAVE_SDCC_4] = &qhs_sdc4,
+	[SLAVE_SE_CLK_CTL] = &qhs_se_clk_ctl,
+	[SLAVE_TCSR] = &qhs_tcsr,
+	[SLAVE_TLMM] = &qhs_tlmm,
+	[SLAVE_TSC_CFG] = &qhs_tsc_cfg,
+	[SLAVE_UFS_MEM_CFG] = &qhs_ufs_mem_cfg,
+	[SLAVE_USB2] = &qhs_usb2,
+	[SLAVE_USB3_0] = &qhs_usb3_0,
+	[SLAVE_USB3_1] = &qhs_usb3_1,
+	[SLAVE_VENUS_CFG] = &qhs_venus_cfg,
+	[SLAVE_COMPUTENOC_CFG] = &qss_computenoc_cfg,
+	[SLAVE_PCIE_NOC_CFG] = &qss_pcie_noc_cfg,
+	[SLAVE_QTC_CFG] = &qss_qtc_cfg,
+	[SLAVE_QDSS_STM] = &xs_qdss_stm,
+	[SLAVE_SYS_TCU0_CFG] = &xs_sys_tcu0_cfg,
+	[SLAVE_SYS_TCU1_CFG] = &xs_sys_tcu1_cfg,
+	[SLAVE_SYS_TCU2_CFG] = &xs_sys_tcu2_cfg,
+};
+
+static const struct regmap_config nord_cnoc_cfg_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0xd200,
+	.fast_io = true,
+};
+
+static const struct qcom_icc_desc nord_cnoc_cfg = {
+	.config = &nord_cnoc_cfg_regmap_config,
+	.nodes = cnoc_cfg_nodes,
+	.num_nodes = ARRAY_SIZE(cnoc_cfg_nodes),
+	.bcms = cnoc_cfg_bcms,
+	.num_bcms = ARRAY_SIZE(cnoc_cfg_bcms),
+};
+
+static struct qcom_icc_bcm * const cnoc_main_bcms[] = {
+	&bcm_cn0,
+};
+
+static struct qcom_icc_node * const cnoc_main_nodes[] = {
+	[MASTER_MM_RSCC] = &qhm_mm_rscc,
+	[MASTER_HSCNOC_CNOC] = &qnm_hscnoc,
+	[SLAVE_AOSS] = &qhs_aoss,
+	[SLAVE_HBCU] = &qhs_hbcu,
+	[SLAVE_IPA_CFG] = &qhs_ipa,
+	[SLAVE_IPC_ROUTER_CFG] = &qhs_ipc_router,
+	[SLAVE_SOCCP] = &qhs_soccp,
+	[SLAVE_TME_CFG] = &qhs_tme_cfg,
+	[SLAVE_PCIE_DMA] = &qns_pcie_dma,
+	[SLAVE_CNOC_CFG] = &qss_cfg,
+	[SLAVE_DDRSS_CFG] = &qss_ddrss_cfg,
+	[SLAVE_IMEM] = &qxs_imem,
+};
+
+static const struct regmap_config nord_cnoc_main_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x1d200,
+	.fast_io = true,
+};
+
+static const struct qcom_icc_desc nord_cnoc_main = {
+	.config = &nord_cnoc_main_regmap_config,
+	.nodes = cnoc_main_nodes,
+	.num_nodes = ARRAY_SIZE(cnoc_main_nodes),
+	.bcms = cnoc_main_bcms,
+	.num_bcms = ARRAY_SIZE(cnoc_main_bcms),
+};
+
+static struct qcom_icc_node * const hpass_ag_noc_nodes[] = {
+	[MASTER_HPASS_PROC_0] = &qnm_hpass_dsp0,
+	[MASTER_HPASS_PROC_1] = &qnm_hpass_dsp1,
+	[MASTER_HPASS_PROC_2] = &qnm_hpass_dsp2,
+	[SLAVE_HPASS_AGNOC_AUDIO] = &qns_hpass_agnoc_audio,
+};
+
+static const struct regmap_config nord_hpass_ag_noc_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x37080,
+	.fast_io = true,
+};
+
+static const struct qcom_icc_desc nord_hpass_ag_noc = {
+	.config = &nord_hpass_ag_noc_regmap_config,
+	.nodes = hpass_ag_noc_nodes,
+	.num_nodes = ARRAY_SIZE(hpass_ag_noc_nodes),
+};
+
+static struct qcom_icc_bcm * const hscnoc_bcms[] = {
+	&bcm_sh0,
+	&bcm_sh1,
+};
+
+static struct qcom_icc_node * const hscnoc_nodes[] = {
+	[MASTER_GPU_TCU] = &alm_gpu_tcu,
+	[MASTER_QTC_TCU] = &alm_qtc,
+	[MASTER_SYS_TCU_0] = &alm_sys_tcu0,
+	[MASTER_SYS_TCU_1] = &alm_sys_tcu1,
+	[MASTER_SYS_TCU_2] = &alm_sys_tcu2,
+	[MASTER_APPSS_PROC] = &chm_apps,
+	[MASTER_A1NOC_TILE_HSCNOC] = &qnm_aggre_north,
+	[MASTER_A2NOC_TILE_HSCNOC] = &qnm_aggre_south,
+	[MASTER_GFX3D] = &qnm_gpu0,
+	[MASTER_GFX3D_1] = &qnm_gpu1,
+	[MASTER_HPASS_ADAS_HSCNOC] = &qnm_hpass_adas_hscnoc,
+	[MASTER_HPASS_AUDIO_HSCNOC] = &qnm_hpass_audio_hscnoc,
+	[MASTER_MNOC_HF_MEM_NOC] = &qnm_mnoc_hf,
+	[MASTER_MNOC_SF_MEM_NOC] = &qnm_mnoc_sf,
+	[MASTER_NSP0_HSCNOC] = &qnm_nsp0_hscnoc,
+	[MASTER_NSP1_HSCNOC] = &qnm_nsp1_hscnoc,
+	[MASTER_NSP2_HSCNOC] = &qnm_nsp2_hscnoc,
+	[MASTER_NSP3_HSCNOC] = &qnm_nsp3_hscnoc,
+	[MASTER_ANOC_PCIE_GEM_NOC] = &qnm_pcie,
+	[MASTER_SAILSS_MD0_HSCNOC] = &qnm_sailss_md0_hscnoc,
+	[MASTER_SNOC_SF_MEM_NOC] = &qnm_snoc_sf,
+	[MASTER_GIC] = &xm_gic,
+	[SLAVE_HSCNOC_CNOC] = &qns_hscnoc_cnoc,
+	[SLAVE_LLCC] = &qns_llcc,
+	[SLAVE_MEM_NOC_PCIE_SNOC] = &qns_pcie,
+};
+
+static const struct regmap_config nord_hscnoc_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x45080,
+	.fast_io = true,
+};
+
+static const struct qcom_icc_desc nord_hscnoc = {
+	.config = &nord_hscnoc_regmap_config,
+	.nodes = hscnoc_nodes,
+	.num_nodes = ARRAY_SIZE(hscnoc_nodes),
+	.bcms = hscnoc_bcms,
+	.num_bcms = ARRAY_SIZE(hscnoc_bcms),
+};
+
+static struct qcom_icc_bcm * const mc_virt_bcms[] = {
+	&bcm_mc0,
+};
+
+static struct qcom_icc_node * const mc_virt_nodes[] = {
+	[MASTER_LLCC] = &llcc_mc,
+	[SLAVE_EBI1] = &ebi,
+};
+
+static const struct qcom_icc_desc nord_mc_virt = {
+	.nodes = mc_virt_nodes,
+	.num_nodes = ARRAY_SIZE(mc_virt_nodes),
+	.bcms = mc_virt_bcms,
+	.num_bcms = ARRAY_SIZE(mc_virt_bcms),
+};
+
+static struct qcom_icc_bcm * const mmss_noc_bcms[] = {
+	&bcm_mm0,
+	&bcm_mm1,
+};
+
+static struct qcom_icc_node * const mmss_noc_nodes[] = {
+	[MASTER_CAMNOC_HF] = &qnm_camnoc_hf,
+	[MASTER_CAMNOC_NRT_ICP_SF] = &qnm_camnoc_nrt_icp_sf,
+	[MASTER_CAMNOC_RT_CDM_SF] = &qnm_camnoc_rt_cdm_sf,
+	[MASTER_CAMNOC_SF] = &qnm_camnoc_sf,
+	[MASTER_DPRX0] = &qnm_dprx0,
+	[MASTER_DPRX1] = &qnm_dprx1,
+	[MASTER_MDP0] = &qnm_mdp0,
+	[MASTER_MDP1] = &qnm_mdp1,
+	[MASTER_VIDEO_CV_PROC] = &qnm_video_cv_cpu,
+	[MASTER_VIDEO_EVA] = &qnm_video_eva,
+	[MASTER_VIDEO_MVP0] = &qnm_video_mvp0,
+	[MASTER_VIDEO_MVP1] = &qnm_video_mvp1,
+	[MASTER_VIDEO_V_PROC] = &qnm_video_v_cpu,
+	[SLAVE_MNOC_HF_MEM_NOC] = &qns_mem_noc_hf,
+	[SLAVE_MNOC_SF_MEM_NOC] = &qns_mem_noc_sf,
+};
+
+static const struct regmap_config nord_mmss_noc_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x72800,
+	.fast_io = true,
+};
+
+static const struct qcom_icc_desc nord_mmss_noc = {
+	.config = &nord_mmss_noc_regmap_config,
+	.nodes = mmss_noc_nodes,
+	.num_nodes = ARRAY_SIZE(mmss_noc_nodes),
+	.bcms = mmss_noc_bcms,
+	.num_bcms = ARRAY_SIZE(mmss_noc_bcms),
+};
+
+static struct qcom_icc_bcm * const nsp_data_noc_0_bcms[] = {
+	&bcm_c0n0,
+};
+
+static struct qcom_icc_node * const nsp_data_noc_0_nodes[] = {
+	[MASTER_NSP0_PROC] = &qnm_nsp_data00,
+	[SLAVE_NSP0_HSC_NOC] = &qns_nsp0_hsc_noc,
+};
+
+static const struct regmap_config nord_nsp_data_noc_0_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x2a200,
+	.fast_io = true,
+};
+
+static const struct qcom_icc_desc nord_nsp_data_noc_0 = {
+	.config = &nord_nsp_data_noc_0_regmap_config,
+	.nodes = nsp_data_noc_0_nodes,
+	.num_nodes = ARRAY_SIZE(nsp_data_noc_0_nodes),
+	.bcms = nsp_data_noc_0_bcms,
+	.num_bcms = ARRAY_SIZE(nsp_data_noc_0_bcms),
+};
+
+static struct qcom_icc_bcm * const nsp_data_noc_1_bcms[] = {
+	&bcm_c1n0,
+};
+
+static struct qcom_icc_node * const nsp_data_noc_1_nodes[] = {
+	[MASTER_NSP1_PROC] = &qnm_nsp_data01,
+	[SLAVE_NSP1_HSC_NOC] = &qns_nsp1_hsc_noc,
+};
+
+static const struct regmap_config nord_nsp_data_noc_1_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x2a200,
+	.fast_io = true,
+};
+
+static const struct qcom_icc_desc nord_nsp_data_noc_1 = {
+	.config = &nord_nsp_data_noc_1_regmap_config,
+	.nodes = nsp_data_noc_1_nodes,
+	.num_nodes = ARRAY_SIZE(nsp_data_noc_1_nodes),
+	.bcms = nsp_data_noc_1_bcms,
+	.num_bcms = ARRAY_SIZE(nsp_data_noc_1_bcms),
+};
+
+static struct qcom_icc_bcm * const nsp_data_noc_2_bcms[] = {
+	&bcm_c2n0,
+};
+
+static struct qcom_icc_node * const nsp_data_noc_2_nodes[] = {
+	[MASTER_NSP2_PROC] = &qnm_nsp_data02,
+	[SLAVE_NSP2_HSC_NOC] = &qns_nsp2_hsc_noc,
+};
+
+static const struct regmap_config nord_nsp_data_noc_2_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x2a200,
+	.fast_io = true,
+};
+
+static const struct qcom_icc_desc nord_nsp_data_noc_2 = {
+	.config = &nord_nsp_data_noc_2_regmap_config,
+	.nodes = nsp_data_noc_2_nodes,
+	.num_nodes = ARRAY_SIZE(nsp_data_noc_2_nodes),
+	.bcms = nsp_data_noc_2_bcms,
+	.num_bcms = ARRAY_SIZE(nsp_data_noc_2_bcms),
+};
+
+static struct qcom_icc_bcm * const nsp_data_noc_3_bcms[] = {
+	&bcm_c3n0,
+};
+
+static struct qcom_icc_node * const nsp_data_noc_3_nodes[] = {
+	[MASTER_NSP3_PROC] = &qnm_nsp_data03,
+	[SLAVE_NSP3_HSC_NOC] = &qns_nsp3_hsc_noc,
+};
+
+static const struct regmap_config nord_nsp_data_noc_3_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x2a200,
+	.fast_io = true,
+};
+
+static const struct qcom_icc_desc nord_nsp_data_noc_3 = {
+	.config = &nord_nsp_data_noc_3_regmap_config,
+	.nodes = nsp_data_noc_3_nodes,
+	.num_nodes = ARRAY_SIZE(nsp_data_noc_3_nodes),
+	.bcms = nsp_data_noc_3_bcms,
+	.num_bcms = ARRAY_SIZE(nsp_data_noc_3_bcms),
+};
+
+static struct qcom_icc_node * const pcie_cfg_nodes[] = {
+	[MASTER_PCIE_NOC_CFG] = &qsm_pcie_noc_cfg,
+	[SLAVE_PCIE_AHB2PHY_CFG] = &qhs_pcie_ahb2phy_cfg,
+	[SLAVE_PCIE_CFG_0] = &qhs_pcie_cfg_0,
+	[SLAVE_PCIE_CFG_1] = &qhs_pcie_cfg_1,
+	[SLAVE_PCIE_CFG_2] = &qhs_pcie_cfg_2,
+	[SLAVE_PCIE_CFG_3] = &qhs_pcie_cfg_3,
+	[SLAVE_PCIE_DMA_0_CFG] = &qhs_pcie_dma_0_cfg,
+	[SLAVE_PCIE_DMA_1_CFG] = &qhs_pcie_dma_1_cfg,
+	[SLAVE_PCIE_DMA_2_CFG] = &qhs_pcie_dma_2_cfg,
+};
+
+static const struct regmap_config nord_pcie_cfg_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x7200,
+	.fast_io = true,
+};
+
+static const struct qcom_icc_desc nord_pcie_cfg = {
+	.config = &nord_pcie_cfg_regmap_config,
+	.nodes = pcie_cfg_nodes,
+	.num_nodes = ARRAY_SIZE(pcie_cfg_nodes),
+};
+
+static struct qcom_icc_bcm * const pcie_data_inbound_bcms[] = {
+	&bcm_sn1,
+};
+
+static struct qcom_icc_node * const pcie_data_inbound_nodes[] = {
+	[MASTER_PCIE_DMA_0] = &qxm_pcie_dma_0,
+	[MASTER_PCIE_DMA_1] = &qxm_pcie_dma_1,
+	[MASTER_PCIE_DMA_2] = &qxm_pcie_dma_2,
+	[MASTER_PCIE_0] = &xm_pcie_0,
+	[MASTER_PCIE_1] = &xm_pcie_1,
+	[MASTER_PCIE_2] = &xm_pcie_2,
+	[MASTER_PCIE_3] = &xm_pcie_3,
+	[SLAVE_PCIE_HSCNOC] = &qns_pcie_hscnoc,
+	[SLAVE_PCIE_OBNOC_DMA] = &qns_pcie_obnoc_dma,
+};
+
+static const struct regmap_config nord_pcie_data_inbound_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x4b080,
+	.fast_io = true,
+};
+
+static const struct qcom_icc_desc nord_pcie_data_inbound = {
+	.config = &nord_pcie_data_inbound_regmap_config,
+	.nodes = pcie_data_inbound_nodes,
+	.num_nodes = ARRAY_SIZE(pcie_data_inbound_nodes),
+	.bcms = pcie_data_inbound_bcms,
+	.num_bcms = ARRAY_SIZE(pcie_data_inbound_bcms),
+};
+
+static struct qcom_icc_bcm * const pcie_data_outbound_bcms[] = {
+	&bcm_cn0,
+};
+
+static struct qcom_icc_node * const pcie_data_outbound_nodes[] = {
+	[MASTER_CNOC_PCIE_DMA] = &qnm_cnoc_pcie_dma,
+	[MASTER_ANOC_PCIE_HSCNOC] = &qnm_hscnoc_pcie,
+	[MASTER_PCIE_IBNOC_DMA] = &qnm_pcie_ibnoc_dma,
+	[SLAVE_PCIE_DMA_0] = &qxs_pcie_dma_0,
+	[SLAVE_PCIE_DMA_1] = &qxs_pcie_dma_1,
+	[SLAVE_PCIE_DMA_2] = &qxs_pcie_dma_2,
+	[SLAVE_PCIE_0] = &xs_pcie_0,
+	[SLAVE_PCIE_1] = &xs_pcie_1,
+	[SLAVE_PCIE_2] = &xs_pcie_2,
+	[SLAVE_PCIE_3] = &xs_pcie_3,
+};
+
+static const struct regmap_config nord_pcie_data_outbound_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x17000,
+	.fast_io = true,
+};
+
+static const struct qcom_icc_desc nord_pcie_data_outbound = {
+	.config = &nord_pcie_data_outbound_regmap_config,
+	.nodes = pcie_data_outbound_nodes,
+	.num_nodes = ARRAY_SIZE(pcie_data_outbound_nodes),
+	.bcms = pcie_data_outbound_bcms,
+	.num_bcms = ARRAY_SIZE(pcie_data_outbound_bcms),
+};
+
+static struct qcom_icc_bcm * const system_noc_bcms[] = {
+	&bcm_sn0,
+	&bcm_sn1,
+	&bcm_sn2,
+	&bcm_sn3,
+};
+
+static struct qcom_icc_node * const system_noc_nodes[] = {
+	[MASTER_A1NOC_SNOC] = &qnm_aggre1_noc,
+	[MASTER_A2NOC_SNOC] = &qnm_aggre2_noc,
+	[MASTER_CNOC_SNOC] = &qnm_cnoc_data,
+	[MASTER_NSINOC_SNOC] = &qnm_nsi_noc,
+	[MASTER_SAFE_DMA] = &qnm_safe_dma,
+	[SLAVE_SNOC_HSCNOC_SF] = &qns_hscnoc_sf,
+};
+
+static const struct regmap_config nord_system_noc_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x1c080,
+	.fast_io = true,
+};
+
+static const struct qcom_icc_desc nord_system_noc = {
+	.config = &nord_system_noc_regmap_config,
+	.nodes = system_noc_nodes,
+	.num_nodes = ARRAY_SIZE(system_noc_nodes),
+	.bcms = system_noc_bcms,
+	.num_bcms = ARRAY_SIZE(system_noc_bcms),
+};
+
+static const struct of_device_id qnoc_of_match[] = {
+	{ .compatible = "qcom,nord-aggre1-noc", .data = &nord_aggre1_noc },
+	{ .compatible = "qcom,nord-aggre1-noc-tile", .data = &nord_aggre1_noc_tile },
+	{ .compatible = "qcom,nord-aggre2-noc", .data = &nord_aggre2_noc },
+	{ .compatible = "qcom,nord-aggre2-noc-tile", .data = &nord_aggre2_noc_tile },
+	{ .compatible = "qcom,nord-clk-virt", .data = &nord_clk_virt },
+	{ .compatible = "qcom,nord-cnoc-cfg", .data = &nord_cnoc_cfg },
+	{ .compatible = "qcom,nord-cnoc-main", .data = &nord_cnoc_main },
+	{ .compatible = "qcom,nord-hpass-ag-noc", .data = &nord_hpass_ag_noc },
+	{ .compatible = "qcom,nord-hscnoc", .data = &nord_hscnoc },
+	{ .compatible = "qcom,nord-mc-virt", .data = &nord_mc_virt },
+	{ .compatible = "qcom,nord-mmss-noc", .data = &nord_mmss_noc },
+	{ .compatible = "qcom,nord-nsp-data-noc-0", .data = &nord_nsp_data_noc_0 },
+	{ .compatible = "qcom,nord-nsp-data-noc-1", .data = &nord_nsp_data_noc_1 },
+	{ .compatible = "qcom,nord-nsp-data-noc-2", .data = &nord_nsp_data_noc_2 },
+	{ .compatible = "qcom,nord-nsp-data-noc-3", .data = &nord_nsp_data_noc_3 },
+	{ .compatible = "qcom,nord-pcie-cfg", .data = &nord_pcie_cfg },
+	{ .compatible = "qcom,nord-pcie-data-inbound", .data = &nord_pcie_data_inbound },
+	{ .compatible = "qcom,nord-pcie-data-outbound", .data = &nord_pcie_data_outbound },
+	{ .compatible = "qcom,nord-system-noc", .data = &nord_system_noc },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, qnoc_of_match);
+
+static struct platform_driver qnoc_driver = {
+	.probe = qcom_icc_rpmh_probe,
+	.remove = qcom_icc_rpmh_remove,
+	.driver = {
+		.name = "qnoc-nord",
+		.of_match_table = qnoc_of_match,
+		.sync_state = icc_sync_state,
+	},
+};
+
+static int __init qnoc_driver_init(void)
+{
+	return platform_driver_register(&qnoc_driver);
+}
+core_initcall(qnoc_driver_init);
+
+static void __exit qnoc_driver_exit(void)
+{
+	platform_driver_unregister(&qnoc_driver);
+}
+module_exit(qnoc_driver_exit);
+
+MODULE_DESCRIPTION("Qualcomm Nord NoC driver");
+MODULE_LICENSE("GPL");
-- 
2.43.0


^ permalink raw reply related

* [PATCH v4] pmdomain: imx: Make IMX8M/IMX9 BLK_CTRL tristate
From: Zhipeng Wang @ 2026-04-20  2:22 UTC (permalink / raw)
  To: ulfh, Frank.Li, s.hauer
  Cc: kernel, festevam, linux-pm, imx, linux-arm-kernel, linux-kernel,
	xuegang.liu, jindong.yue

Convert IMX8M_BLK_CTRL and IMX9_BLK_CTRL from bool to tristate
to allow building as loadable modules.

This change is required to support Android devices using Generic Kernel
Image (GKI) kernels, where SoC-specific drivers must be built as loadable
modules rather than built into the core kernel image.

For i.MX8M and i.MX9 devices running Android with GKI kernels, the
BLK_CTRL drivers therefore need to be loadable. Without tristate
support, power domains cannot be initialized correctly, making these
systems non-functional under GKI.

Add prompt strings to make these options visible and configurable
in menuconfig, keeping them enabled by default on appropriate platforms.

Also remove the IMX_GPCV2_PM_DOMAINS dependency from IMX9_BLK_CTRL.
This dependency was incorrect from the beginning because i.MX93 uses a
different power domain architecture compared to i.MX8M series:

- i.MX8M uses GPCv2 (General Power Controller v2) for power domain
  management, hence IMX8M_BLK_CTRL correctly depends on it.

- i.MX93 uses BLK_CTRL directly without GPCv2. The hardware doesn't
  have GPCv2 at all.

Signed-off-by: Zhipeng Wang <zhipeng.wang_1@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
---
Changes in v4:
- No functional changes
- Added detailed explanation about GKI (Generic Kernel Image) requirement
  in the commit message to clarify why tristate support is needed for
  Android devices

Changes in v3:
- No functional changes
- Fixed typo reported by Frank
- Added Reviewed-by tag from Frank Li

Changes in v2:
- No functional changes
- Expanded commit message to explain the architectural differences between
  i.MX8M and i.MX93 power domain management
- Clarified why IMX_GPCV2_PM_DOMAINS dependency removal is correct for
  i.MX93
---
 drivers/pmdomain/imx/Kconfig | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/pmdomain/imx/Kconfig b/drivers/pmdomain/imx/Kconfig
index 00203615c65e..9168d183b0c5 100644
--- a/drivers/pmdomain/imx/Kconfig
+++ b/drivers/pmdomain/imx/Kconfig
@@ -10,15 +10,18 @@ config IMX_GPCV2_PM_DOMAINS
 	default y if SOC_IMX7D
 
 config IMX8M_BLK_CTRL
-	bool
-	default SOC_IMX8M && IMX_GPCV2_PM_DOMAINS
+	tristate "i.MX8M BLK CTRL driver"
+	depends on SOC_IMX8M
+	depends on IMX_GPCV2_PM_DOMAINS
 	depends on PM_GENERIC_DOMAINS
 	depends on COMMON_CLK
+	default y
 
 config IMX9_BLK_CTRL
-	bool
-	default SOC_IMX9 && IMX_GPCV2_PM_DOMAINS
+	tristate "i.MX93 BLK CTRL driver"
+	depends on SOC_IMX9
 	depends on PM_GENERIC_DOMAINS
+	default y
 
 config IMX_SCU_PD
 	bool "IMX SCU Power Domain driver"
-- 
2.34.1


^ permalink raw reply related

* RE: [EXT] Re: [PATCH v2] pmdomain: imx: Make IMX8M/IMX9 BLK_CTRL tristate
From: Zhipeng Wang @ 2026-04-20  2:26 UTC (permalink / raw)
  To: Daniel Baluta (OSS), Marco Felsch
  Cc: ulfh@kernel.org, Frank Li, s.hauer@pengutronix.de,
	imx@lists.linux.dev, linux-pm@vger.kernel.org, Xuegang Liu,
	Jindong Yue, linux-kernel@vger.kernel.org, kernel@pengutronix.de,
	festevam@gmail.com, linux-arm-kernel@lists.infradead.org
In-Reply-To: <d44a60ff-c8a3-4347-9199-def61e855066@oss.nxp.com>



> -----Original Message-----
> From: Daniel Baluta (OSS) <daniel.baluta@oss.nxp.com>
> Sent: 2026年4月16日 14:04
> To: Zhipeng Wang <zhipeng.wang_1@nxp.com>; Marco Felsch
> <m.felsch@pengutronix.de>
> Cc: ulfh@kernel.org; Frank Li <frank.li@nxp.com>; s.hauer@pengutronix.de;
> imx@lists.linux.dev; linux-pm@vger.kernel.org; Xuegang Liu
> <xuegang.liu@nxp.com>; Jindong Yue <jindong.yue@nxp.com>;
> linux-kernel@vger.kernel.org; kernel@pengutronix.de; festevam@gmail.com;
> linux-arm-kernel@lists.infradead.org
> Subject: Re: [EXT] Re: [PATCH v2] pmdomain: imx: Make IMX8M/IMX9
> BLK_CTRL tristate
> 
> On 4/14/26 04:59, Zhipeng Wang wrote:
> >  > On 26-04-13, Zhipeng Wang wrote:
> >>> Convert IMX8M_BLK_CTRL and IMX9_BLK_CTRL from bool to tristate to
> >>> allow building as loadable modules.
> >> Out of curiosity, why do you want to have a PM driver to be buildable
> >> as module?
> >>
> >> Regards,
> >>   Marco
> >>
> > Hi Marco,
> >
> > Thank you for your question.
> >
> > The primary motivation is to support Google's GKI (Generic Kernel
> > Image) requirement for Android devices.
> >
> > GKI separates the kernel into two parts:
> > 1. A unified kernel image (GKI) that is common across all Android
> > devices 2. Vendor-specific drivers that must be built as loadable
> > modules
> >
> > Under the GKI architecture, SoC-specific drivers like IMX8M/IMX9
> > BLK_CTRL cannot be built into the core kernel image. Instead, they
> > must be loadable modules that vendors can ship separately. This allows:
> >
> > - A single kernel binary to support multiple hardware platforms
> > - Vendors to update their drivers independently without rebuilding the
> > entire kernel
> > - Better compliance with Android's kernel update and security policies
> >
> Can you please add the below line in the commit message?

Hi Daniel,

Thank you! V4 sent.

BRs,
Zhipeng
> > For i.MX8M/i.MX9 devices running Android with GKI kernels, the
> > BLK_CTRL drivers need to be loaded as modules during boot. Without
> > tristate support, these devices cannot properly initialize their power
> > domains, making them non-functional under GKI.
> 


^ permalink raw reply

* Re: [RFC PATCH 2/2] kernel/module: Decouple klp and ftrace from load_module
From: Masami Hiramatsu @ 2026-04-20  2:27 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Petr Pavlu, Song Chen, rafael, lenb, mturquette, sboyd,
	viresh.kumar, agk, snitzer, mpatocka, bmarzins, song, yukuai,
	linan122, jason.wessel, danielt, dianders, horms, davem, edumazet,
	kuba, pabeni, paulmck, frederic, mcgrof, da.gomez, samitolvanen,
	atomlin, jpoimboe, jikos, mbenes, joe.lawrence, rostedt, mhiramat,
	mark.rutland, mathieu.desnoyers, linux-modules, linux-kernel,
	linux-trace-kernel, linux-acpi, linux-clk, linux-pm,
	live-patching, dm-devel, linux-raid, kgdb-bugreport, netdev
In-Reply-To: <aeD2_FrFL6E3dbAC@pathway.suse.cz>

On Thu, 16 Apr 2026 16:49:32 +0200
Petr Mladek <pmladek@suse.com> wrote:

> On Thu 2026-04-16 13:18:30, Petr Pavlu wrote:
> > On 4/15/26 8:43 AM, Song Chen wrote:
> > > On 4/14/26 22:33, Petr Pavlu wrote:
> > >> On 4/13/26 10:07 AM, chensong_2000@189.cn wrote:
> > >>> diff --git a/include/linux/module.h b/include/linux/module.h
> > >>> index 14f391b186c6..0bdd56f9defd 100644
> > >>> --- a/include/linux/module.h
> > >>> +++ b/include/linux/module.h
> > >>> @@ -308,6 +308,14 @@ enum module_state {
> > >>>       MODULE_STATE_COMING,    /* Full formed, running module_init. */
> > >>>       MODULE_STATE_GOING,    /* Going away. */
> > >>>       MODULE_STATE_UNFORMED,    /* Still setting it up. */
> > >>> +    MODULE_STATE_FORMED,
> > >>
> > >> I don't see a reason to add a new module state. Why is it necessary and
> > >> how does it fit with the existing states?
> > >>
> > > because once notifier fails in state MODULE_STATE_UNFORMED (now only ftrace has someting to do in this state), notifier chain will roll back by calling blocking_notifier_call_chain_robust, i'm afraid MODULE_STATE_GOING is going to jeopardise the notifers which don't handle it appropriately, like:
> > > 
> > > case MODULE_STATE_COMING:
> > >      kmalloc();
> > > case MODULE_STATE_GOING:
> > >      kfree();
> > 
> > My understanding is that the current module "state machine" operates as
> > follows. Transitions marked with an asterisk (*) are announced via the
> > module notifier.
> > 
> > ---> UNFORMED --*> COMING --*> LIVE --*> GOING -.
> >         ^            |                     ^    |
> >         |            '---------------------*    |
> >         '---------------------------------------'
> > 
> > The new code aims to replace the current ftrace_module_init() call in
> > load_module(). To achieve this, it adds a notification for the UNFORMED
> > state (only when loading a module) and introduces a new FORMED state for
> > rollback. FORMED is purely a fake state because it never appears in
> > module::state. The new structure is as follows:
> > 
> >         ,--*> (FORMED)
> >         |
> > --*> UNFORMED --*> COMING --*> LIVE --*> GOING -.
> >         ^            |                     ^    |
> >         |            '---------------------*    |
> >         '---------------------------------------'
> > 
> > I'm afraid this is quite complex and inconsistent. Unless it can be kept
> > simple, we would be just replacing one special handling with a different
> > complexity, which is not worth it.
> 
> > >>
> > >>> +    if (err)
> > >>> +        goto ddebug_cleanup;
> > >>>         /* Finally it's fully formed, ready to start executing. */
> > >>>       err = complete_formation(mod, info);
> > >>> -    if (err)
> > >>> +    if (err) {
> > >>> +        blocking_notifier_call_chain_reverse(&module_notify_list,
> > >>> +                MODULE_STATE_FORMED, mod);
> > >>>           goto ddebug_cleanup;
> > >>> +    }
> > >>>   -    err = prepare_coming_module(mod);
> > >>> +    err = prepare_module_state_transaction(mod,
> > >>> +                MODULE_STATE_COMING, MODULE_STATE_GOING);
> > >>>       if (err)
> > >>>           goto bug_cleanup;
> > >>>   @@ -3522,7 +3519,6 @@ static int load_module(struct load_info *info, const char __user *uargs,
> > >>>       destroy_params(mod->kp, mod->num_kp);
> > >>>       blocking_notifier_call_chain(&module_notify_list,
> > >>>                        MODULE_STATE_GOING, mod);
> > >>
> > >> My understanding is that all notifier chains for MODULE_STATE_GOING
> > >> should be reversed.
> > > yes, all, from lowest priority notifier to highest.
> > > I will resend patch 1 which was failed due to my proxy setting.
> > 
> > What I meant here is that the call:
> > 
> > blocking_notifier_call_chain(&module_notify_list, MODULE_STATE_GOING, mod);
> > 
> > should be replaced with:
> > 
> > blocking_notifier_call_chain_reverse(&module_notify_list, MODULE_STATE_GOING, mod);
> > 
> > > 
> > >>
> > >>> -    klp_module_going(mod);
> > >>>    bug_cleanup:
> > >>>       mod->state = MODULE_STATE_GOING;
> > >>>       /* module_bug_cleanup needs module_mutex protection */
> > >>
> > >> The patch removes the klp_module_going() cleanup call in load_module().
> > >> Similarly, the ftrace_release_mod() call under the ddebug_cleanup label
> > >> should be removed and appropriately replaced with a cleanup via
> > >> a notifier.
> > >>
> > >     err = prepare_module_state_transaction(mod,
> > >                 MODULE_STATE_UNFORMED, MODULE_STATE_FORMED);
> > >     if (err)
> > >         goto ddebug_cleanup;
> > > 
> > > ftrace will be cleanup in blocking_notifier_call_chain_robust rolling back.
> > > 
> > >     err = prepare_module_state_transaction(mod,
> > >                 MODULE_STATE_COMING, MODULE_STATE_GOING);
> > > 
> > > each notifier including ftrace and klp will be cleanup in blocking_notifier_call_chain_robust rolling back.
> > > 
> > > if all notifiers are successful in MODULE_STATE_COMING, they all will be clean up in
> > >  coming_cleanup:
> > >     mod->state = MODULE_STATE_GOING;
> > >     destroy_params(mod->kp, mod->num_kp);
> > >     blocking_notifier_call_chain(&module_notify_list,
> > >                      MODULE_STATE_GOING, mod);
> > > 
> > > if  something wrong underneath.
> > 
> > My point is that the patch leaves a call to ftrace_release_mod() in
> > load_module(), which I expected to be handled via a notifier.
> 
> I think that I have got it. The ftrace code needs two notifiers when
> the module is being loaded and two when it is going.
> 
> This is why Sond added the new state. But I think that we would
> need two new states to call:
> 
>     + ftrace_module_init() in MODULE_STATE_UNFORMED
>     + ftrace_module_enable() in MODULE_STATE_FORMED
> 
> and
> 
>     + ftrace_free_mem() in MODULE_STATE_PRE_GOING
>     + ftrace_free_mem() in MODULE_STATE_GOING
> 
> 
> By using the ascii art:
> 
>  -*> UNFORMED -*> FORMED -> COMING -*> LIVE -*> PRE_GOING -*> GOING -.
>               |          |         |                ^           ^    ^
>               |          |         '----------------'           |    |
>               |          '--------------------------------------'    |
>               '------------------------------------------------------'
> 
> 
> But I think that this is not worth it.

Agree.

If this needs to be ordered so strictly, why we will use a "single"
module notifier chain for this complex situation?

I think the notifier call chain is just for notice a single signal,
instead of sending several different signals, especially if there is
any dependency among the callbacks.

If notification callbacks need to be ordered, they are currently
sorted by representing priority numerically, but this is quite
fragile for updating. It has to look up other registered priorities
and adjust the order among dependencies each time. For this reason,
this mechanism is not suitable for global ordering. (It's like line
numbers in BASIC.)
It is probably only useful for representing dependencies between
two components maintained by the same maintainer.

I'm against a general-purpose system that makes everything modular.
It unnecessarily complicates things. If there are processes that
require strict ordering, especially processes that must be performed
before each stage as part of the framework, they should be called
directly from the framework, not via notification callbacks.

This makes it simpler and more robust to maintain.

Only the framework's end users should utilize notification callbacks.

Thank you,


> 
> Best Regards,
> Petr
> 


-- 
Masami Hiramatsu (Google) <mhiramat@kernel.org>

^ permalink raw reply

* Re: [RFC PATCH 1/2] kernel/notifier: replace single-linked list with double-linked list for reverse traversal
From: Masami Hiramatsu @ 2026-04-20  5:44 UTC (permalink / raw)
  To: chensong_2000
  Cc: rafael, lenb, mturquette, sboyd, viresh.kumar, agk, snitzer,
	mpatocka, bmarzins, song, yukuai, linan122, jason.wessel, danielt,
	dianders, horms, davem, edumazet, kuba, pabeni, paulmck, frederic,
	mcgrof, petr.pavlu, da.gomez, samitolvanen, atomlin, jpoimboe,
	jikos, mbenes, pmladek, joe.lawrence, rostedt, mark.rutland,
	mathieu.desnoyers, linux-modules, linux-kernel,
	linux-trace-kernel, linux-acpi, linux-clk, linux-pm,
	live-patching, dm-devel, linux-raid, kgdb-bugreport, netdev
In-Reply-To: <20260415070137.17860-1-chensong_2000@189.cn>

Hi Song,

On Wed, 15 Apr 2026 15:01:37 +0800
chensong_2000@189.cn wrote:

> From: Song Chen <chensong_2000@189.cn>
> 
> The current notifier chain implementation uses a single-linked list
> (struct notifier_block *next), which only supports forward traversal
> in priority order. This makes it difficult to handle cleanup/teardown
> scenarios that require notifiers to be called in reverse priority order.

What about introducing a new notification callback API that allows you
to describe dependencies between callback functions?

For example, when registering a callback, you could register a string
as an ID and specify whether to call it before or after that ID,
or you could register a comparison function that is called when adding
to a list. (I prefer @name and @depends fields so that it can be easily
maintained.)

This would allow for better dependency building when adding to the list.

> 
> A concrete example is the ordering dependency between ftrace and
> livepatch during module load/unload. see the detail here [1].

If this only concerns notification callback issues with the ftrace
and livepatch modules, it's far more robust to simply call the
necessary processing directly when the modules load and unload,
rather than registering notification callbacks externally.

There are fprobe, kprobe and its trace-events, all of them are using
ftrace as its fundation layer. In this case, I always needs to
consider callback order when a module is unloaded.

If ftrace is working as a part of module callbacks, it will conflict
with fprobe/kprobe module callback. Of course we can reorder it with
modifying its priority. But this is ugly, because when we introduce
a new other feature which depends on another layer, we need to
reorder the callback's priority number on the list.

Based on the above, I don't think this can be resolved simply by
changing the list of notification callbacks to a bidirectional list.

Thank you,

-- 
Masami Hiramatsu (Google) <mhiramat@kernel.org>

^ permalink raw reply

* Re: [PATCH v2 1/3] MAINTAINERS: Move Peter De Schrijver to CREDITS
From: Geert Uytterhoeven @ 2026-04-20  6:50 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Aaro Koskinen, linux-tegra, linux-arm-kernel, linux-pm,
	linux-omap, linux-m68k, devicetree, linux-kernel, Paul Walmsley
In-Reply-To: <20260417131549.3154534-1-thierry.reding@kernel.org>

Hi Thierry,

On Fri, 17 Apr 2026 at 15:15, Thierry Reding <thierry.reding@kernel.org> wrote:
> From: Thierry Reding <treding@nvidia.com>
>
> Peter sadly passed away a while back. Paul did a much better job at
> finding the right words to mourn this loss than I ever could, so I will
> leave this link here:
>
>   https://lore.kernel.org/lkml/alpine.DEB.2.21.999.2407240345480.11116@utopia.booyaka.com/T/#u
>
> Co-developed-by: Paul Walmsley <pjw@kernel.org>
> Co-developed-by: Aaro Koskinen <aaro.koskinen@iki.fi>
> Co-developed-by: Geert Uytterhoeven <geert@linux-m68k.org>

   "every Co-developed-by: must be immediately
    followed by a Signed-off-by: of the associated co-author."

https://elixir.bootlin.com/linux/v7.0/source/Documentation/process/submitting-patches.rst#L506

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>

> Signed-off-by: Thierry Reding <treding@nvidia.com>
> ---
> Changes in v2:
> - add more missing entries

Thanks!

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* [PATCH] dt-bindings: thermal: qcom-tsens: Document Nord Temperature Sensor
From: Shawn Guo @ 2026-04-20  6:54 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio,
	Dmitry Baryshkov, Bartosz Golaszewski, Deepti Jaggi, linux-pm,
	devicetree, linux-arm-msm, linux-kernel, Shawn Guo

From: Deepti Jaggi <deepti.jaggi@oss.qualcomm.com>

Add compatible for Temperature Sensor (TSENS) of Nord SoC with
a fallback on qcom,tsens-v2.

Signed-off-by: Deepti Jaggi <deepti.jaggi@oss.qualcomm.com>
Signed-off-by: Shawn Guo <shengchao.guo@oss.qualcomm.com>
---
 Documentation/devicetree/bindings/thermal/qcom-tsens.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml
index 7d34ba00e684..e65ebc6f1698 100644
--- a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml
+++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml
@@ -58,6 +58,7 @@ properties:
               - qcom,glymur-tsens
               - qcom,kaanapali-tsens
               - qcom,milos-tsens
+              - qcom,nord-tsens
               - qcom,msm8953-tsens
               - qcom,msm8996-tsens
               - qcom,msm8998-tsens
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH v2 4/9] pmdomain: core: Add initial fine grained sync_state support
From: Geert Uytterhoeven @ 2026-04-20  8:49 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Saravana Kannan, Rafael J . Wysocki, Greg Kroah-Hartman, linux-pm,
	Sudeep Holla, Cristian Marussi, Kevin Hilman, Stephen Boyd,
	Marek Szyprowski, Bjorn Andersson, Abel Vesa, Peng Fan,
	Tomi Valkeinen, Maulik Shah, Konrad Dybcio, Thierry Reding,
	Jonathan Hunter, Dmitry Baryshkov, linux-arm-kernel, linux-kernel,
	Geert Uytterhoeven
In-Reply-To: <20260410104058.83748-5-ulf.hansson@linaro.org>

Hi Ulf,

On Fri, 10 Apr 2026 at 12:41, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> A onecell (#power-domain-cells = <1 or 2>; in DT) power domain provider
> typically provides multiple independent power domains, each with their own
> corresponding consumers. In these cases we have to wait for all consumers
> for all the provided power domains before the ->sync_state() callback gets
> called for the supplier.
>
> In a first step to improve this, let's implement support for fine grained
> sync_state support a per genpd basis by using the ->queue_sync_state()
> callback. To take step by step, let's initially limit the improvement to
> the internal genpd provider driver and to its corresponding genpd devices
> for onecell providers.
>
> Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

Thanks for your patch!

> --- a/drivers/pmdomain/core.c
> +++ b/drivers/pmdomain/core.c

> +static void genpd_parse_for_consumer(struct device_node *sup,
> +                                    struct device_node *con)
> +{
> +       struct generic_pm_domain *genpd;
> +       int i;

unsigned int?

> +
> +       for (i = 0; ; i++) {

... and you could move it inside the for-statement.

> +               struct of_phandle_args pd_args;
> +
> +               if (of_parse_phandle_with_args(con, "power-domains",
> +                                              "#power-domain-cells",
> +                                               i, &pd_args))

Checkpatch reports a superfluous space before the "i".

> +                       break;

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* Re: [PATCH] dt-bindings: thermal: qcom-tsens: Document Nord Temperature Sensor
From: Pankaj Patil @ 2026-04-20  9:19 UTC (permalink / raw)
  To: Shawn Guo, Daniel Lezcano
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio,
	Dmitry Baryshkov, Bartosz Golaszewski, Deepti Jaggi, linux-pm,
	devicetree, linux-arm-msm, linux-kernel
In-Reply-To: <20260420065409.1249030-1-shengchao.guo@oss.qualcomm.com>

On 4/20/2026 12:24 PM, Shawn Guo wrote:
> From: Deepti Jaggi <deepti.jaggi@oss.qualcomm.com>
> 
> Add compatible for Temperature Sensor (TSENS) of Nord SoC with
> a fallback on qcom,tsens-v2.
> 
> Signed-off-by: Deepti Jaggi <deepti.jaggi@oss.qualcomm.com>
> Signed-off-by: Shawn Guo <shengchao.guo@oss.qualcomm.com>

Reviewed-by: Pankaj Patil <pankaj.patil@oss.qualcomm.com>

> ---
>  Documentation/devicetree/bindings/thermal/qcom-tsens.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml
> index 7d34ba00e684..e65ebc6f1698 100644
> --- a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml
> +++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml
> @@ -58,6 +58,7 @@ properties:
>                - qcom,glymur-tsens
>                - qcom,kaanapali-tsens
>                - qcom,milos-tsens
> +              - qcom,nord-tsens
>                - qcom,msm8953-tsens
>                - qcom,msm8996-tsens
>                - qcom,msm8998-tsens


^ permalink raw reply

* Re: [Pre-CfP] LPC2026: Power management and thermal control micro-conference
From: Rafael J. Wysocki @ 2026-04-20 10:22 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Rafael J. Wysocki, Linux PM, Daniel Lezcano, Lukasz Luba,
	Morten Rasmussen, Sudeep Holla, Ulf Hansson, Christian Loehle,
	Artem Bityutskiy, Ricardo Neri, Srinivas Pandruvada, Viresh Kumar,
	Pierre Gondois, Dietmar Eggemann, amit.kucheria
In-Reply-To: <8677457e-5d8a-4f30-a688-a4613f17c740@oss.qualcomm.com>

On Fri, Apr 17, 2026 at 5:05 PM Daniel Lezcano
<daniel.lezcano@oss.qualcomm.com> wrote:
>
>
> Resending with the correct email address for Amit :/
>
> On 4/17/26 17:02, Daniel Lezcano wrote:
> >
> > + Amit Kucheria
> >
> > On 3/26/26 15:35, Rafael J. Wysocki wrote:
> >> Hi All,
> >>
> >> I'm looking for topic suggestions to be included in the power
> >> management and thermal control micro-conference submission for
> >> LPC2026.  The deadline for submitting LPC u-conf proposals is April
> >> 23, so if there are any topics you'd like to be covered, please let me
> >> know within the next 2 weeks.
> >
> > I've some topics to be addressed regarding thermal issues, limitations
> > and enhancements, suspend/resume limitations, powercap enhancements,
> > user space resource management and may be power supply.
> >
> > I'm still in the process of collecting information, sorting them out and
> > doing a selection of what is the most relevant for LPC. I should send
> > the selection in a couple of days (may be 3)
> >
> > Is one title + a couple of sentences fine for each topic as pre-CfP ?

A title line itself should be sufficient - I only need a list of
prospective topics to be added to the proposal.

Also, the deadline for proposal submissions is April 23, so if you can
send me something earlier, please do so.

^ permalink raw reply

* Re: [Pre-CfP] LPC2026: Power management and thermal control micro-conference
From: Daniel Lezcano @ 2026-04-20 11:06 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux PM, Daniel Lezcano, Lukasz Luba, Morten Rasmussen,
	Sudeep Holla, Ulf Hansson, Christian Loehle, Artem Bityutskiy,
	Ricardo Neri, Srinivas Pandruvada, Viresh Kumar, Pierre Gondois,
	Dietmar Eggemann, amit.kucheria
In-Reply-To: <CAJZ5v0hb-RT5ZaRyea+ge5jMsv1g4i-0ONpc2O4uqKe+6A+bsw@mail.gmail.com>

On 4/20/26 12:22, Rafael J. Wysocki wrote:
> On Fri, Apr 17, 2026 at 5:05 PM Daniel Lezcano
> <daniel.lezcano@oss.qualcomm.com> wrote:
>>
>>
>> Resending with the correct email address for Amit :/
>>
>> On 4/17/26 17:02, Daniel Lezcano wrote:
>>>
>>> + Amit Kucheria
>>>
>>> On 3/26/26 15:35, Rafael J. Wysocki wrote:
>>>> Hi All,
>>>>
>>>> I'm looking for topic suggestions to be included in the power
>>>> management and thermal control micro-conference submission for
>>>> LPC2026.  The deadline for submitting LPC u-conf proposals is April
>>>> 23, so if there are any topics you'd like to be covered, please let me
>>>> know within the next 2 weeks.
>>>
>>> I've some topics to be addressed regarding thermal issues, limitations
>>> and enhancements, suspend/resume limitations, powercap enhancements,
>>> user space resource management and may be power supply.
>>>
>>> I'm still in the process of collecting information, sorting them out and
>>> doing a selection of what is the most relevant for LPC. I should send
>>> the selection in a couple of days (may be 3)
>>>
>>> Is one title + a couple of sentences fine for each topic as pre-CfP ?
> 
> A title line itself should be sufficient - I only need a list of
> prospective topics to be added to the proposal.
> 
> Also, the deadline for proposal submissions is April 23, so if you can
> send me something earlier, please do so.

Yes, will do

^ permalink raw reply


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