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 <[email protected]> AuthorDate: Tue Nov 7 20:12:32 2023 +0800 Thermal: Add dummy driver Signed-off-by: wangjianyu3 <[email protected]> --- 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; +}
