You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2024/09/23 00:57:43 UTC
(nuttx) 07/19: Thermal: Add dummy driver
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit d43f0272e5072d3b364101333a78f632cf033e9a
Author: wangjianyu3 <wa...@xiaomi.com>
AuthorDate: Tue Nov 7 20:12:32 2023 +0800
Thermal: Add dummy driver
Signed-off-by: wangjianyu3 <wa...@xiaomi.com>
---
drivers/thermal/Kconfig | 23 +++
drivers/thermal/Make.defs | 4 +
drivers/thermal/thermal_core.c | 9 ++
drivers/thermal/thermal_core.h | 6 +
drivers/thermal/thermal_dummy.c | 347 ++++++++++++++++++++++++++++++++++++++++
5 files changed, 389 insertions(+)
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 4f795a97b2..9808707006 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -37,4 +37,27 @@ config THERMAL_PROCFS
---help---
Enable thermal procfs.
+config THERMAL_DUMMY
+ bool "Thermal dummy driver"
+ default n
+ ---help---
+ Enable thermal dummy driver.
+
+if THERMAL_DUMMY
+
+config THERMAL_DUMMY_POLLING_DELAY
+ int "Polling delay"
+ default 200
+ ---help---
+ Polling delay(tick).
+
+config THERMAL_DUMMY_CPUFREQ
+ bool "Dummy cpufreq driver"
+ default n
+ depends on CPUFREQ
+ ---help---
+ Enable cpufreq dummy driver.
+
+endif # THERMAL_DUMMY
+
endif # THERMAL
diff --git a/drivers/thermal/Make.defs b/drivers/thermal/Make.defs
index 9e95fe4cfe..28b0af0c63 100644
--- a/drivers/thermal/Make.defs
+++ b/drivers/thermal/Make.defs
@@ -36,6 +36,10 @@ ifeq ($(CONFIG_THERMAL_PROCFS),y)
CSRCS += thermal_procfs.c
endif
+ifeq ($(CONFIG_THERMAL_DUMMY),y)
+CSRCS += thermal_dummy.c
+endif
+
DEPPATH += --dep-path thermal
VPATH += thermal
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 741bd9a84a..d430c01200 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -926,6 +926,15 @@ int thermal_init(void)
}
#endif
+#ifdef CONFIG_THERMAL_DUMMY
+ ret = thermal_dummy_init();
+ if (ret < 0)
+ {
+ therr("Dummy driver init failed!\n");
+ return ret;
+ }
+#endif
+
#ifdef CONFIG_THERMAL_CDEV_CPUFREQ
if (NULL == thermal_cpufreq_cooling_register())
{
diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h
index 8b7bcc37f5..e60ac51417 100644
--- a/drivers/thermal/thermal_core.h
+++ b/drivers/thermal/thermal_core.h
@@ -89,4 +89,10 @@ int thermal_zone_procfs_register(FAR struct thermal_zone_device_s *zdev);
void thermal_zone_procfs_unregister(FAR struct thermal_zone_device_s *zdev);
#endif
+/* Dummy Driver */
+
+#ifdef CONFIG_THERMAL_DUMMY
+int thermal_dummy_init(void);
+#endif
+
#endif /* __DRIVERS_THERMAL_THERMAL_CORE_H */
diff --git a/drivers/thermal/thermal_dummy.c b/drivers/thermal/thermal_dummy.c
new file mode 100644
index 0000000000..fa45968b9c
--- /dev/null
+++ b/drivers/thermal/thermal_dummy.c
@@ -0,0 +1,347 @@
+/****************************************************************************
+ * drivers/thermal/thermal_dummy.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/cpufreq.h>
+#include <nuttx/thermal.h>
+
+#include <sys/param.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define DUMMY_TEMP_RANGE_LOW 45
+#define DUMMY_TEMP_RANGE_HIGH 90
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct dummy_zone_device_s
+{
+ int temperature;
+ bool raising;
+};
+
+struct dummy_cooling_device_s
+{
+ unsigned int cur_state;
+ unsigned int max_state;
+};
+
+struct dummy_cpufreq_driver_s
+{
+ struct cpufreq_driver driver;
+ const struct cpufreq_frequency_table *table;
+ size_t table_len;
+ int current;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Zone Device */
+
+static int dummy_zdev_get_temp (FAR struct thermal_zone_device_s *zdev,
+ FAR int *temp);
+static int dummy_zdev_set_trips(FAR struct thermal_zone_device_s *zdev,
+ int low, int high);
+
+/* Cooling Device */
+
+static int
+dummy_cdev_get_max_state(FAR struct thermal_cooling_device_s *cdev,
+ FAR unsigned int *state);
+static int
+dummy_cdev_get_state (FAR struct thermal_cooling_device_s *cdev,
+ FAR unsigned int *state);
+static int
+dummy_cdev_set_state (FAR struct thermal_cooling_device_s *cdev,
+ unsigned int state);
+
+/* CPU Freq */
+
+#ifdef CONFIG_THERMAL_DUMMY_CPUFREQ
+FAR static const struct cpufreq_frequency_table *
+dummy_cpufreq_get_table(FAR struct cpufreq_policy *driver);
+static int dummy_cpufreq_target_index(FAR struct cpufreq_policy *driver,
+ unsigned int index);
+static int dummy_cpufreq_get_frequency(FAR struct cpufreq_policy *driver);
+static int dummy_cpufreq_suspend(FAR struct cpufreq_policy *driver);
+static int dummy_cpufreq_resume (FAR struct cpufreq_policy *driver);
+#endif /* CONFIG_THERMAL_DUMMY_CPUFREQ */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Bind */
+
+static const struct thermal_zone_trip_s g_dummy_trips[] =
+{
+ {.name = "cpu_crit", .temp = 90, .hyst = 10, .type = THERMAL_CRITICAL},
+ {.name = "cpu_alert1", .temp = 70, .hyst = 10, .type = THERMAL_NORMAL},
+ {.name = "cpu_alert0", .temp = 60, .hyst = 10, .type = THERMAL_NORMAL},
+};
+
+static const struct thermal_zone_map_s g_dummy_maps[] =
+{
+ {
+ .trip_name = "cpu_alert1",
+ .cdev_name = "cpufreq",
+ .low = 3,
+ .high = THERMAL_NO_LIMIT,
+ .weight = 20
+ },
+ {
+ .trip_name = "cpu_alert1",
+ .cdev_name = "fan0",
+ .low = THERMAL_NO_LIMIT,
+ .high = THERMAL_NO_LIMIT,
+ .weight = 20
+ },
+ {
+ .trip_name = "cpu_alert0",
+ .cdev_name = "cpufreq",
+ .low = THERMAL_NO_LIMIT,
+ .high = 2,
+ .weight = 20
+ },
+};
+
+static const struct thermal_zone_params_s g_dummy_params =
+{
+ .gov_name = "step_wise",
+ .polling_delay = CONFIG_THERMAL_DUMMY_POLLING_DELAY,
+ .trips = g_dummy_trips,
+ .num_trips = nitems(g_dummy_trips),
+ .maps = g_dummy_maps,
+ .num_maps = nitems(g_dummy_maps),
+};
+
+/* Zone device */
+
+static const struct thermal_zone_device_ops_s g_dummy_zone_ops =
+{
+ .get_temp = dummy_zdev_get_temp,
+ .set_trips = dummy_zdev_set_trips,
+};
+
+static struct dummy_zone_device_s g_dummy_zone =
+{
+ .temperature = 45,
+ .raising = true,
+};
+
+/* Cooling Device - fan0 */
+
+static struct dummy_cooling_device_s g_dummy_fan0_data =
+{
+ .cur_state = 0,
+ .max_state = 16,
+};
+
+static const struct thermal_cooling_device_ops_s g_dummy_fan0_ops =
+{
+ .set_state = dummy_cdev_set_state,
+ .get_state = dummy_cdev_get_state,
+ .get_max_state = dummy_cdev_get_max_state,
+};
+
+/* Cooling Device - cpufreq */
+
+#ifdef CONFIG_THERMAL_DUMMY_CPUFREQ
+static const struct cpufreq_frequency_table g_dummy_cpufreq_table[] =
+{
+ {100},
+ {300},
+ {500},
+ {700},
+ {900},
+ {CPUFREQ_TABLE_END},
+};
+static struct dummy_cpufreq_driver_s g_dummy_cpufreq_driver =
+{
+ .driver =
+ {
+ dummy_cpufreq_get_table,
+ dummy_cpufreq_target_index,
+ dummy_cpufreq_get_frequency,
+ dummy_cpufreq_suspend,
+ dummy_cpufreq_resume,
+ },
+ .table = g_dummy_cpufreq_table,
+ .table_len = nitems(g_dummy_cpufreq_table),
+};
+#endif /* CONFIG_THERMAL_DUMMY_CPUFREQ */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/* Dummy Cooling Device Operations */
+
+static int dummy_cdev_set_state(FAR struct thermal_cooling_device_s *cdev,
+ unsigned int state)
+{
+ FAR struct dummy_cooling_device_s *c = cdev->devdata;
+
+ c->cur_state = state;
+ return OK;
+}
+
+static int dummy_cdev_get_state(FAR struct thermal_cooling_device_s *cdev,
+ FAR unsigned int *state)
+{
+ FAR struct dummy_cooling_device_s *c = cdev->devdata;
+
+ *state = c->cur_state;
+ return OK;
+}
+
+static int
+dummy_cdev_get_max_state(FAR struct thermal_cooling_device_s *cdev,
+ FAR unsigned int *state)
+{
+ FAR struct dummy_cooling_device_s *c = cdev->devdata;
+
+ *state = c->max_state;
+ return OK;
+}
+
+/* Sensor */
+
+static int dummy_zdev_get_temp(FAR struct thermal_zone_device_s *zdev,
+ FAR int *temp)
+{
+ FAR struct dummy_zone_device_s *s = zdev->devdata;
+
+ if (s->temperature >= DUMMY_TEMP_RANGE_HIGH)
+ {
+ s->raising = false;
+ }
+ else if (s->temperature <= DUMMY_TEMP_RANGE_LOW)
+ {
+ s->raising = true;
+ }
+
+ if (s->raising)
+ {
+ s->temperature++;
+ }
+ else
+ {
+ s->temperature--;
+ }
+
+ *temp = s->temperature;
+ return OK;
+}
+
+static int dummy_zdev_set_trips(FAR struct thermal_zone_device_s *zdev,
+ int low, int high)
+{
+ return OK;
+}
+
+#ifdef CONFIG_THERMAL_DUMMY_CPUFREQ
+static FAR const struct cpufreq_frequency_table *dummy_cpufreq_get_table(
+ FAR struct cpufreq_policy *driver)
+{
+ FAR struct dummy_cpufreq_driver_s **dummy =
+ (FAR struct dummy_cpufreq_driver_s **)driver;
+ return (*dummy)->table;
+}
+
+static int dummy_cpufreq_target_index(FAR struct cpufreq_policy *driver,
+ unsigned int index)
+{
+ FAR struct dummy_cpufreq_driver_s **dummy =
+ (FAR struct dummy_cpufreq_driver_s **)driver;
+
+ DEBUGASSERT(index >= 0 && index < (*dummy)->table_len);
+
+ (*dummy)->current = (*dummy)->table[index].frequency;
+ return 0;
+}
+
+static int dummy_cpufreq_get_frequency(FAR struct cpufreq_policy *driver)
+{
+ FAR struct dummy_cpufreq_driver_s **dummy =
+ (FAR struct dummy_cpufreq_driver_s **)driver;
+
+ return (*dummy)->current;
+}
+
+static int dummy_cpufreq_suspend(FAR struct cpufreq_policy *driver)
+{
+ return 0;
+}
+
+static int dummy_cpufreq_resume(FAR struct cpufreq_policy *driver)
+{
+ return 0;
+}
+#endif /* CONFIG_THERMAL_DUMMY_CPUFREQ */
+
+int thermal_dummy_init(void)
+{
+ FAR struct thermal_cooling_device_s *cdev;
+ FAR struct thermal_zone_device_s *zdev;
+ int ret = OK;
+
+ /* Driver - CPUFreq */
+
+#ifdef CONFIG_THERMAL_DUMMY_CPUFREQ
+ ret = cpufreq_init(&g_dummy_cpufreq_driver.driver);
+ if (ret < 0)
+ {
+ therr("Dummy cpufreq driver init failed!\n");
+ return ret;
+ }
+#endif /* CONFIG_THERMAL_DUMMY_CPUFREQ */
+
+ /* Cooling Device */
+
+ cdev = thermal_cooling_device_register("fan0", &g_dummy_fan0_data,
+ &g_dummy_fan0_ops);
+ if (cdev == NULL)
+ {
+ therr("Register cooling device fan0 failed!\n");
+ return -ENOTSUP;
+ }
+
+ /* Zone Device */
+
+ zdev = thermal_zone_device_register("cpu-thermal", &g_dummy_zone,
+ &g_dummy_zone_ops, &g_dummy_params);
+ if (zdev == NULL)
+ {
+ therr("Register zone deivce failed!\n");
+ return -ENOTSUP;
+ }
+
+ return ret;
+}