Add thermal framework
Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
This commit is contained in:
parent
b78c9a7067
commit
d1b87bd021
31
Kconfig
31
Kconfig
@ -1936,6 +1936,37 @@ config DEBUG_SPI_INFO
|
|||||||
|
|
||||||
endif # DEBUG_SPI
|
endif # DEBUG_SPI
|
||||||
|
|
||||||
|
config DEBUG_THERMAL
|
||||||
|
bool "Thermal Debug Features"
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
Enable thermal debug features.
|
||||||
|
|
||||||
|
if DEBUG_THERMAL
|
||||||
|
|
||||||
|
config DEBUG_THERMAL_ERROR
|
||||||
|
bool "Thermal Error Output"
|
||||||
|
default n
|
||||||
|
depends on DEBUG_ERROR
|
||||||
|
---help---
|
||||||
|
Enable thermal error output to SYSLOG.
|
||||||
|
|
||||||
|
config DEBUG_THERMAL_WARN
|
||||||
|
bool "Thermal Warnings Output"
|
||||||
|
default n
|
||||||
|
depends on DEBUG_WARN
|
||||||
|
---help---
|
||||||
|
Enable thermal warning output to SYSLOG.
|
||||||
|
|
||||||
|
config DEBUG_THERMAL_INFO
|
||||||
|
bool "Thermal Informational Output"
|
||||||
|
default n
|
||||||
|
depends on DEBUG_INFO
|
||||||
|
---help---
|
||||||
|
Enable thermal informational output to SYSLOG.
|
||||||
|
|
||||||
|
endif # DEBUG_THERMAL
|
||||||
|
|
||||||
config DEBUG_TIMER
|
config DEBUG_TIMER
|
||||||
bool "Timer Debug Features"
|
bool "Timer Debug Features"
|
||||||
default n
|
default n
|
||||||
|
@ -42,6 +42,7 @@ source "drivers/rpmsg/Kconfig"
|
|||||||
source "drivers/rptun/Kconfig"
|
source "drivers/rptun/Kconfig"
|
||||||
source "drivers/sensors/Kconfig"
|
source "drivers/sensors/Kconfig"
|
||||||
source "drivers/serial/Kconfig"
|
source "drivers/serial/Kconfig"
|
||||||
|
source "drivers/thermal/Kconfig"
|
||||||
source "drivers/usbdev/Kconfig"
|
source "drivers/usbdev/Kconfig"
|
||||||
source "drivers/usbhost/Kconfig"
|
source "drivers/usbhost/Kconfig"
|
||||||
source "drivers/usbmisc/Kconfig"
|
source "drivers/usbmisc/Kconfig"
|
||||||
|
@ -63,6 +63,7 @@ include sensors/Make.defs
|
|||||||
include serial/Make.defs
|
include serial/Make.defs
|
||||||
include spi/Make.defs
|
include spi/Make.defs
|
||||||
include syslog/Make.defs
|
include syslog/Make.defs
|
||||||
|
include thermal/Make.defs
|
||||||
include timers/Make.defs
|
include timers/Make.defs
|
||||||
include usbdev/Make.defs
|
include usbdev/Make.defs
|
||||||
include usbhost/Make.defs
|
include usbhost/Make.defs
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
#include <nuttx/serial/uart_ram.h>
|
#include <nuttx/serial/uart_ram.h>
|
||||||
#include <nuttx/syslog/syslog.h>
|
#include <nuttx/syslog/syslog.h>
|
||||||
#include <nuttx/syslog/syslog_console.h>
|
#include <nuttx/syslog/syslog_console.h>
|
||||||
|
#include <nuttx/thermal.h>
|
||||||
#include <nuttx/trace.h>
|
#include <nuttx/trace.h>
|
||||||
#include <nuttx/usrsock/usrsock_rpmsg.h>
|
#include <nuttx/usrsock/usrsock_rpmsg.h>
|
||||||
#include <nuttx/virtio/virtio.h>
|
#include <nuttx/virtio/virtio.h>
|
||||||
@ -271,5 +272,9 @@ void drivers_initialize(void)
|
|||||||
optee_register();
|
optee_register();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_THERMAL
|
||||||
|
thermal_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
drivers_trace_end();
|
drivers_trace_end();
|
||||||
}
|
}
|
||||||
|
20
drivers/thermal/Kconfig
Normal file
20
drivers/thermal/Kconfig
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#
|
||||||
|
# For a description of the syntax of this configuration file,
|
||||||
|
# see the file kconfig-language.txt in the NuttX tools repository.
|
||||||
|
#
|
||||||
|
|
||||||
|
menuconfig THERMAL
|
||||||
|
bool "Thermal framework"
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
Enable thermal framework.
|
||||||
|
|
||||||
|
if THERMAL
|
||||||
|
|
||||||
|
config THERMAL_DEFAULT_GOVERNOR
|
||||||
|
string "Thermal default governor name"
|
||||||
|
default "step_wise"
|
||||||
|
---help---
|
||||||
|
Default governor name.
|
||||||
|
|
||||||
|
endif # THERMAL
|
30
drivers/thermal/Make.defs
Normal file
30
drivers/thermal/Make.defs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
############################################################################
|
||||||
|
# drivers/thermal/Make.defs
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
# Include thermal sources
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_THERMAL),y)
|
||||||
|
|
||||||
|
CSRCS += thermal_core.c
|
||||||
|
|
||||||
|
DEPPATH += --dep-path thermal
|
||||||
|
VPATH += thermal
|
||||||
|
|
||||||
|
endif
|
843
drivers/thermal/thermal_core.c
Normal file
843
drivers/thermal/thermal_core.c
Normal file
@ -0,0 +1,843 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* drivers/thermal/thermal_core.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/kmalloc.h>
|
||||||
|
|
||||||
|
#include <debug.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/boardctl.h>
|
||||||
|
|
||||||
|
#include "thermal_core.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Function Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int zone_bind_cooling (FAR struct thermal_zone_device_s *zdev,
|
||||||
|
int trip,
|
||||||
|
FAR struct thermal_cooling_device_s *cdev,
|
||||||
|
unsigned int upper, unsigned int lower,
|
||||||
|
unsigned int weight);
|
||||||
|
static void zone_unbind_cooling(FAR struct thermal_zone_device_s *zdev,
|
||||||
|
int trip,
|
||||||
|
FAR struct thermal_cooling_device_s *cdev);
|
||||||
|
|
||||||
|
static FAR struct thermal_governor_s *
|
||||||
|
find_governor_by_name (FAR const char *name);
|
||||||
|
static int zone_set_governor (FAR struct thermal_zone_device_s *zdev,
|
||||||
|
FAR struct thermal_governor_s *gov);
|
||||||
|
|
||||||
|
static void device_bind (FAR struct thermal_zone_device_s *zdev,
|
||||||
|
FAR struct thermal_cooling_device_s *cdev);
|
||||||
|
static void device_unbind (FAR struct thermal_zone_device_s *zdev,
|
||||||
|
FAR struct thermal_cooling_device_s *cdev);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static struct list_node
|
||||||
|
g_cooling_dev_list = LIST_INITIAL_VALUE(g_cooling_dev_list);
|
||||||
|
|
||||||
|
static struct list_node
|
||||||
|
g_governor_list = LIST_INITIAL_VALUE(g_governor_list);
|
||||||
|
|
||||||
|
static struct list_node
|
||||||
|
g_zone_dev_list = LIST_INITIAL_VALUE(g_zone_dev_list);
|
||||||
|
|
||||||
|
static mutex_t g_thermal_lock = NXMUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
static FAR struct thermal_governor_s *g_def_governor = NULL;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int zone_set_governor(FAR struct thermal_zone_device_s *zdev,
|
||||||
|
FAR struct thermal_governor_s *gov)
|
||||||
|
{
|
||||||
|
int ret = OK;
|
||||||
|
|
||||||
|
/* The caller must use `g_thermal_lock` to protect zones and governors */
|
||||||
|
|
||||||
|
if (zdev->governor && zdev->governor->unbind_from_tz)
|
||||||
|
{
|
||||||
|
zdev->governor->unbind_from_tz(zdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gov && gov->bind_to_tz)
|
||||||
|
{
|
||||||
|
ret = gov->bind_to_tz(zdev);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
if (zdev->governor->bind_to_tz(zdev) < 0)
|
||||||
|
{
|
||||||
|
zdev->governor = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zdev->governor = gov;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zone_bind_cooling(FAR struct thermal_zone_device_s *zdev,
|
||||||
|
int trip,
|
||||||
|
FAR struct thermal_cooling_device_s *cdev,
|
||||||
|
unsigned int upper, unsigned int lower,
|
||||||
|
unsigned int weight)
|
||||||
|
{
|
||||||
|
FAR struct thermal_instance_s *ins;
|
||||||
|
FAR struct thermal_instance_s *pos;
|
||||||
|
unsigned int max_state;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = cdev->ops->get_max_state(cdev, &max_state);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
therr("Get max state failed!\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
list_for_every_entry(&zdev->instance_list, pos,
|
||||||
|
struct thermal_instance_s, zdev_node)
|
||||||
|
{
|
||||||
|
if (zdev == pos->zdev && cdev == pos->cdev && trip == pos->trip)
|
||||||
|
{
|
||||||
|
thwarn("Instance %s %s %d already exist!",
|
||||||
|
zdev->name, cdev->name, trip);
|
||||||
|
return -EEXIST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ins = kmm_malloc(sizeof(struct thermal_instance_s));
|
||||||
|
if (!ins)
|
||||||
|
{
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
ins->zdev = zdev;
|
||||||
|
ins->cdev = cdev;
|
||||||
|
ins->trip = trip;
|
||||||
|
ins->target = THERMAL_NO_TARGET;
|
||||||
|
|
||||||
|
if (lower == THERMAL_NO_LIMIT)
|
||||||
|
{
|
||||||
|
ins->lower = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ins->lower = lower;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (upper == THERMAL_NO_LIMIT)
|
||||||
|
{
|
||||||
|
ins->upper = max_state;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ins->upper = upper;
|
||||||
|
}
|
||||||
|
|
||||||
|
ins->weight = weight;
|
||||||
|
|
||||||
|
thinfo("Adding instance zdev:%-4s cdev:%-4s h:%2u l:%2u t:%d\n",
|
||||||
|
zdev->name, cdev->name, ins->upper, ins->lower, ins->trip);
|
||||||
|
|
||||||
|
list_add_tail(&zdev->instance_list, &ins->zdev_node);
|
||||||
|
list_add_tail(&cdev->instance_list, &ins->cdev_node);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void zone_unbind_cooling(FAR struct thermal_zone_device_s *zdev,
|
||||||
|
int trip,
|
||||||
|
FAR struct thermal_cooling_device_s *cdev)
|
||||||
|
{
|
||||||
|
FAR struct thermal_instance_s *ins;
|
||||||
|
|
||||||
|
list_for_every_entry(&zdev->instance_list, ins,
|
||||||
|
struct thermal_instance_s, zdev_node)
|
||||||
|
{
|
||||||
|
if (zdev == ins->zdev && cdev == ins->cdev && trip == ins->trip)
|
||||||
|
{
|
||||||
|
list_delete(&ins->zdev_node);
|
||||||
|
list_delete(&ins->cdev_node);
|
||||||
|
|
||||||
|
kmm_free(ins);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void device_bind(FAR struct thermal_zone_device_s *zdev,
|
||||||
|
FAR struct thermal_cooling_device_s *cdev)
|
||||||
|
{
|
||||||
|
FAR const struct thermal_zone_map_s *map;
|
||||||
|
FAR const struct thermal_zone_trip_s *trip;
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
for (i = 0; i < zdev->params->num_maps; i++)
|
||||||
|
{
|
||||||
|
map = &zdev->params->maps[i];
|
||||||
|
|
||||||
|
if (strcmp(map->cdev_name, cdev->name))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < zdev->params->num_trips; j++)
|
||||||
|
{
|
||||||
|
trip = &zdev->params->trips[j];
|
||||||
|
if (strcmp(map->trip_name, trip->name))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = zone_bind_cooling(zdev, j, cdev, map->high, map->low,
|
||||||
|
map->weight);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
therr("Failed to bind %s and %s, trip %d\n",
|
||||||
|
zdev->name, cdev->name, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void device_unbind(FAR struct thermal_zone_device_s *zdev,
|
||||||
|
FAR struct thermal_cooling_device_s *cdev)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < zdev->params->num_trips; i++)
|
||||||
|
{
|
||||||
|
zone_unbind_cooling(zdev, i, cdev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static FAR struct thermal_governor_s *
|
||||||
|
find_governor_by_name(FAR const char *name)
|
||||||
|
{
|
||||||
|
FAR struct thermal_governor_s *gov;
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The caller must use `g_thermal_lock` to protect governors */
|
||||||
|
|
||||||
|
list_for_every_entry(&g_governor_list, gov, struct thermal_governor_s,
|
||||||
|
node)
|
||||||
|
{
|
||||||
|
if (!strcmp(gov->name, name))
|
||||||
|
{
|
||||||
|
return gov;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int thermal_zone_enable(FAR struct thermal_zone_device_s *zdev,
|
||||||
|
bool enabled)
|
||||||
|
{
|
||||||
|
nxmutex_lock(&g_thermal_lock);
|
||||||
|
|
||||||
|
if (enabled == zdev->enabled)
|
||||||
|
{
|
||||||
|
nxmutex_unlock(&g_thermal_lock);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
zdev->enabled = enabled;
|
||||||
|
work_cancel_sync(LPWORK, &zdev->monitor);
|
||||||
|
|
||||||
|
nxmutex_unlock(&g_thermal_lock);
|
||||||
|
|
||||||
|
thermal_zone_device_update(zdev);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int thermal_zone_get_trend(FAR struct thermal_zone_device_s *zdev)
|
||||||
|
{
|
||||||
|
enum thermal_trend_e trend;
|
||||||
|
|
||||||
|
if (zdev->ops->get_trend)
|
||||||
|
{
|
||||||
|
if (!zdev->ops->get_trend(zdev, &trend))
|
||||||
|
{
|
||||||
|
return trend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zdev->last_temperature == THERMAL_INVALID_TEMP ||
|
||||||
|
zdev->temperature == THERMAL_INVALID_TEMP)
|
||||||
|
{
|
||||||
|
trend = THERMAL_TREND_STABLE;
|
||||||
|
}
|
||||||
|
else if (zdev->last_temperature > zdev->temperature)
|
||||||
|
{
|
||||||
|
trend = THERMAL_TREND_DROPPING;
|
||||||
|
}
|
||||||
|
else if (zdev->last_temperature < zdev->temperature)
|
||||||
|
{
|
||||||
|
trend = THERMAL_TREND_RAISING;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
trend = THERMAL_TREND_STABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return trend;
|
||||||
|
}
|
||||||
|
|
||||||
|
int thermal_zone_get_trip_temp(FAR struct thermal_zone_device_s *zdev,
|
||||||
|
int trip,
|
||||||
|
FAR int *temp)
|
||||||
|
{
|
||||||
|
if (!temp || trip >= zdev->params->num_trips)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*temp = zdev->params->trips[trip].temp;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int thermal_zone_get_trip_type(FAR struct thermal_zone_device_s *zdev,
|
||||||
|
int trip,
|
||||||
|
FAR enum thermal_trip_type_e *type)
|
||||||
|
{
|
||||||
|
if (!type || trip >= zdev->params->num_trips)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*type = zdev->params->trips[trip].type;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int thermal_zone_get_trip_hyst(FAR struct thermal_zone_device_s *zdev,
|
||||||
|
int trip,
|
||||||
|
FAR int *hyst)
|
||||||
|
{
|
||||||
|
if (!hyst || trip >= zdev->params->num_trips)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*hyst = zdev->params->trips[trip].hyst;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: thermal_register_governor
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Register governor
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* gov - the struct thermal_governor_s addr
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) is returned on success. Otherwise a negated errno value is
|
||||||
|
* returned to indicate the nature of the failure.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int thermal_register_governor(FAR struct thermal_governor_s *gov)
|
||||||
|
{
|
||||||
|
FAR struct thermal_governor_s *pos;
|
||||||
|
|
||||||
|
if (!gov || !gov->throttle)
|
||||||
|
{
|
||||||
|
therr("Invalid governor!\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
nxmutex_lock(&g_thermal_lock);
|
||||||
|
|
||||||
|
list_for_every_entry(&g_governor_list, pos,
|
||||||
|
struct thermal_governor_s, node)
|
||||||
|
{
|
||||||
|
if (!strcmp(gov->name, pos->name))
|
||||||
|
{
|
||||||
|
thwarn("Governor (%s) already exists!", gov->name);
|
||||||
|
nxmutex_unlock(&g_thermal_lock);
|
||||||
|
return -EEXIST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list_add_tail(&g_governor_list, &gov->node);
|
||||||
|
|
||||||
|
thinfo("Register governor %s\n", gov->name);
|
||||||
|
|
||||||
|
/* Default governor */
|
||||||
|
|
||||||
|
if (!strcmp(gov->name, CONFIG_THERMAL_DEFAULT_GOVERNOR))
|
||||||
|
{
|
||||||
|
g_def_governor = gov;
|
||||||
|
thinfo("Default governor %s registered!\n", g_def_governor->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
nxmutex_unlock(&g_thermal_lock);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: thermal_unregister_governor
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Unregister governor
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* gov - the struct thermal_governor_s addr
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void thermal_unregister_governor(FAR struct thermal_governor_s *gov)
|
||||||
|
{
|
||||||
|
FAR struct thermal_zone_device_s *zdev;
|
||||||
|
|
||||||
|
if (!gov)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nxmutex_lock(&g_thermal_lock);
|
||||||
|
|
||||||
|
list_for_every_entry(&g_zone_dev_list, zdev,
|
||||||
|
struct thermal_zone_device_s, node)
|
||||||
|
{
|
||||||
|
if (zdev->governor == gov)
|
||||||
|
{
|
||||||
|
zone_set_governor(zdev, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list_delete(&gov->node);
|
||||||
|
nxmutex_unlock(&g_thermal_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: thermal_cooling_device_register
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Register thermal cooling device.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* name - Name of cooling device
|
||||||
|
* devdata - Device driver data
|
||||||
|
* ops - Operations
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Addr of created cooling device entry.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
FAR struct thermal_cooling_device_s *
|
||||||
|
thermal_cooling_device_register(FAR const char *name, void *devdata,
|
||||||
|
FAR const struct thermal_cooling_device_ops_s *ops)
|
||||||
|
{
|
||||||
|
FAR struct thermal_zone_device_s *zdev;
|
||||||
|
FAR struct thermal_cooling_device_s *cdev;
|
||||||
|
|
||||||
|
nxmutex_lock(&g_thermal_lock);
|
||||||
|
|
||||||
|
list_for_every_entry(&g_cooling_dev_list, cdev,
|
||||||
|
struct thermal_cooling_device_s, node)
|
||||||
|
{
|
||||||
|
if (!strcmp(cdev->name, name))
|
||||||
|
{
|
||||||
|
thwarn("Cooling device (%s) already exists!", name);
|
||||||
|
nxmutex_unlock(&g_thermal_lock);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cdev = kmm_zalloc(sizeof(*cdev));
|
||||||
|
if (!cdev)
|
||||||
|
{
|
||||||
|
therr("Cannot allocate memory for cooling device registering!\n");
|
||||||
|
nxmutex_unlock(&g_thermal_lock);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
strlcpy(cdev->name, name, THERMAL_NAME_LEN);
|
||||||
|
cdev->ops = ops;
|
||||||
|
cdev->devdata = devdata;
|
||||||
|
|
||||||
|
list_initialize(&cdev->instance_list);
|
||||||
|
list_add_tail(&g_cooling_dev_list, &cdev->node);
|
||||||
|
|
||||||
|
list_for_every_entry(&g_zone_dev_list, zdev,
|
||||||
|
struct thermal_zone_device_s, node)
|
||||||
|
{
|
||||||
|
device_bind(zdev, cdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
thinfo("Registered cooling device %s\n", cdev->name);
|
||||||
|
nxmutex_unlock(&g_thermal_lock);
|
||||||
|
|
||||||
|
return cdev;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: thermal_cooling_device_unregister
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Unregister thermal cooling device.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* cdev - Cooling Device
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void
|
||||||
|
thermal_cooling_device_unregister(FAR struct thermal_cooling_device_s *cdev)
|
||||||
|
{
|
||||||
|
FAR struct thermal_zone_device_s *zdev;
|
||||||
|
|
||||||
|
/* Unbind */
|
||||||
|
|
||||||
|
nxmutex_lock(&g_thermal_lock);
|
||||||
|
|
||||||
|
list_delete(&cdev->node);
|
||||||
|
|
||||||
|
list_for_every_entry(&g_zone_dev_list, zdev,
|
||||||
|
struct thermal_zone_device_s, node)
|
||||||
|
{
|
||||||
|
device_unbind(zdev, cdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
kmm_free(cdev);
|
||||||
|
nxmutex_unlock(&g_thermal_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: thermal_cooling_device_update
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Update thermal cooling device.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* cdev - Cooling Device.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void thermal_cooling_device_update(FAR struct thermal_cooling_device_s *cdev)
|
||||||
|
{
|
||||||
|
FAR struct thermal_instance_s *instance;
|
||||||
|
unsigned int target = THERMAL_NO_TARGET;
|
||||||
|
unsigned int current = THERMAL_NO_TARGET;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = cdev->ops->get_state(cdev, ¤t);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
thwarn("Thermal get cooling state failed!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
list_for_every_entry(&cdev->instance_list, instance,
|
||||||
|
struct thermal_instance_s, cdev_node)
|
||||||
|
{
|
||||||
|
if ((instance->target != THERMAL_NO_TARGET) &&
|
||||||
|
(instance->target > target ||
|
||||||
|
target == THERMAL_NO_TARGET))
|
||||||
|
{
|
||||||
|
target = instance->target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target != THERMAL_NO_TARGET && target != current)
|
||||||
|
{
|
||||||
|
ret = cdev->ops->set_state(cdev, target);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
thwarn("Thermal set cooling state of %s failed!\n", cdev->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: thermal_zone_device_register
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Register thermal zone device.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* name - Name of zone.
|
||||||
|
* devdata - Device driver data.
|
||||||
|
* ops - Operations of zone deivce.
|
||||||
|
* params - Parameter of zone device.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Addr of created zone device entry.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
struct thermal_zone_device_s *
|
||||||
|
thermal_zone_device_register(FAR const char *name,
|
||||||
|
FAR void *devdata,
|
||||||
|
FAR const struct thermal_zone_device_ops_s *ops,
|
||||||
|
FAR const struct thermal_zone_params_s *params)
|
||||||
|
{
|
||||||
|
FAR struct thermal_cooling_device_s *cdev;
|
||||||
|
FAR struct thermal_governor_s *gov;
|
||||||
|
FAR struct thermal_zone_device_s *pos;
|
||||||
|
FAR struct thermal_zone_device_s *zdev;
|
||||||
|
|
||||||
|
if (!ops || !ops->get_temp)
|
||||||
|
{
|
||||||
|
therr("Invalid zone operations!\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
nxmutex_lock(&g_thermal_lock);
|
||||||
|
|
||||||
|
list_for_every_entry(&g_zone_dev_list, pos,
|
||||||
|
struct thermal_zone_device_s, node)
|
||||||
|
{
|
||||||
|
if (!strcmp(name, pos->name))
|
||||||
|
{
|
||||||
|
thwarn("Zone device (%s) already exists!", name);
|
||||||
|
nxmutex_unlock(&g_thermal_lock);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zdev = kmm_zalloc(sizeof(struct thermal_zone_device_s));
|
||||||
|
if (!zdev)
|
||||||
|
{
|
||||||
|
nxmutex_unlock(&g_thermal_lock);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
zdev->ops = ops;
|
||||||
|
zdev->devdata = devdata;
|
||||||
|
zdev->enabled = true;
|
||||||
|
|
||||||
|
strlcpy(zdev->name, name, THERMAL_NAME_LEN);
|
||||||
|
|
||||||
|
zdev->params = params;
|
||||||
|
zdev->temperature = THERMAL_INVALID_TEMP;
|
||||||
|
|
||||||
|
list_initialize(&zdev->instance_list);
|
||||||
|
|
||||||
|
/* Set governor */
|
||||||
|
|
||||||
|
gov = find_governor_by_name(zdev->params->gov_name);
|
||||||
|
zone_set_governor(zdev, gov ? gov : g_def_governor);
|
||||||
|
|
||||||
|
thinfo("Set governor of zone %s to %s.\n", zdev->name,
|
||||||
|
zdev->governor ? zdev->governor->name : "");
|
||||||
|
|
||||||
|
list_add_tail(&g_zone_dev_list, &zdev->node);
|
||||||
|
|
||||||
|
list_for_every_entry(&g_cooling_dev_list, cdev,
|
||||||
|
struct thermal_cooling_device_s, node)
|
||||||
|
{
|
||||||
|
device_bind(zdev, cdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
nxmutex_unlock(&g_thermal_lock);
|
||||||
|
|
||||||
|
thinfo("Registered zone device %s\n", zdev->name);
|
||||||
|
thermal_zone_device_update(zdev);
|
||||||
|
return zdev;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: thermal_zone_device_unregister
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Unregister thermal zone device.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* zdev - Zone Device
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void thermal_zone_device_unregister(FAR struct thermal_zone_device_s *zdev)
|
||||||
|
{
|
||||||
|
FAR struct thermal_cooling_device_s *cdev;
|
||||||
|
|
||||||
|
/* Disable Zone */
|
||||||
|
|
||||||
|
thermal_zone_enable(zdev, false);
|
||||||
|
|
||||||
|
/* Unbind */
|
||||||
|
|
||||||
|
nxmutex_lock(&g_thermal_lock);
|
||||||
|
|
||||||
|
list_for_every_entry(&g_cooling_dev_list, cdev,
|
||||||
|
struct thermal_cooling_device_s, node)
|
||||||
|
{
|
||||||
|
device_unbind(zdev, cdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
list_delete(&zdev->node);
|
||||||
|
zone_set_governor(zdev, NULL);
|
||||||
|
kmm_free(zdev);
|
||||||
|
nxmutex_unlock(&g_thermal_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: thermal_zone_device_update
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Update thermal zone device.
|
||||||
|
* Get temperature from sensor and throttle if necessary.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* zdev - Zone Device
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void thermal_zone_device_update(FAR struct thermal_zone_device_s *zdev)
|
||||||
|
{
|
||||||
|
int trip_high = INT_MAX;
|
||||||
|
int trip_low = INT_MIN;
|
||||||
|
int trip;
|
||||||
|
int temp;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
nxmutex_lock(&g_thermal_lock);
|
||||||
|
|
||||||
|
/* Update termerature */
|
||||||
|
|
||||||
|
if (!zdev->enabled)
|
||||||
|
{
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = zdev->ops->get_temp(zdev, &temp);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
therr("Failed to get temperature from zone %s \n", zdev->name);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
zdev->last_temperature = zdev->temperature;
|
||||||
|
zdev->temperature = temp;
|
||||||
|
|
||||||
|
for (trip = 0; trip < zdev->params->num_trips; trip++)
|
||||||
|
{
|
||||||
|
enum thermal_trip_type_e type;
|
||||||
|
int temp_low;
|
||||||
|
int hyst;
|
||||||
|
|
||||||
|
thermal_zone_get_trip_temp(zdev, trip, &temp);
|
||||||
|
thermal_zone_get_trip_hyst(zdev, trip, &hyst);
|
||||||
|
thermal_zone_get_trip_type(zdev, trip, &type);
|
||||||
|
|
||||||
|
if (zdev->temperature < temp && trip_high > temp)
|
||||||
|
{
|
||||||
|
trip_high = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
temp_low = temp - hyst;
|
||||||
|
|
||||||
|
if (zdev->temperature > temp_low && trip_low < temp_low)
|
||||||
|
{
|
||||||
|
trip_low = temp_low;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Critical */
|
||||||
|
|
||||||
|
if (type == THERMAL_CRITICAL && zdev->temperature >= temp)
|
||||||
|
{
|
||||||
|
therr("Thermal critical (%d), resetting...\n", zdev->temperature);
|
||||||
|
#ifdef CONFIG_BOARDCTL_RESET
|
||||||
|
boardctl(BOARDIOC_RESET, BOARDIOC_SOFTRESETCAUSE_THERMAL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if (zdev->governor)
|
||||||
|
{
|
||||||
|
zdev->governor->throttle(zdev, trip);
|
||||||
|
}
|
||||||
|
else if(g_def_governor)
|
||||||
|
{
|
||||||
|
g_def_governor->throttle(zdev, trip);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
therr("No valid governor!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zdev->ops->set_trips)
|
||||||
|
{
|
||||||
|
ret = zdev->ops->set_trips(zdev, trip_low, trip_high);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
thwarn("Set trip points (l:%d, h:%d) for %s failed\n",
|
||||||
|
trip_low, trip_high, zdev->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
work_queue(LPWORK, &zdev->monitor, (worker_t)thermal_zone_device_update,
|
||||||
|
zdev, zdev->params->polling_delay);
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
nxmutex_unlock(&g_thermal_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: thermal_init
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Init thermal framework
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) is returned on success. Otherwise a negated errno value is
|
||||||
|
* returned to indicate the nature of the failure.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int thermal_init(void)
|
||||||
|
{
|
||||||
|
int ret = OK;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
76
drivers/thermal/thermal_core.h
Normal file
76
drivers/thermal/thermal_core.h
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* drivers/thermal/thermal_core.h
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __DRIVERS_THERMAL_THERMAL_CORE_H
|
||||||
|
#define __DRIVERS_THERMAL_THERMAL_CORE_H
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/thermal.h>
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
struct thermal_instance_s
|
||||||
|
{
|
||||||
|
FAR struct thermal_cooling_device_s *cdev;
|
||||||
|
FAR struct thermal_zone_device_s *zdev;
|
||||||
|
|
||||||
|
int trip;
|
||||||
|
|
||||||
|
/* Cooling State */
|
||||||
|
|
||||||
|
unsigned int target; /* Expected Cooling State */
|
||||||
|
unsigned int upper; /* The Maximum cooling state for this trip point */
|
||||||
|
unsigned int lower; /* Minimum cooling state */
|
||||||
|
unsigned int weight;
|
||||||
|
|
||||||
|
struct list_node cdev_node;
|
||||||
|
struct list_node zdev_node;
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Function Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* Cooling Device */
|
||||||
|
|
||||||
|
void
|
||||||
|
thermal_cooling_device_update (FAR struct thermal_cooling_device_s *cdev);
|
||||||
|
|
||||||
|
/* Zone Device */
|
||||||
|
|
||||||
|
int thermal_zone_enable (FAR struct thermal_zone_device_s *zdev,
|
||||||
|
bool enabled);
|
||||||
|
int thermal_zone_get_trend (FAR struct thermal_zone_device_s *zdev);
|
||||||
|
int thermal_zone_get_trip_temp(FAR struct thermal_zone_device_s *zdev,
|
||||||
|
int trip,
|
||||||
|
FAR int *temp);
|
||||||
|
int thermal_zone_get_trip_type(FAR struct thermal_zone_device_s *zdev,
|
||||||
|
int trip,
|
||||||
|
FAR enum thermal_trip_type_e *type);
|
||||||
|
int thermal_zone_get_trip_hyst(FAR struct thermal_zone_device_s *zdev,
|
||||||
|
int trip,
|
||||||
|
FAR int *hyst);
|
||||||
|
|
||||||
|
#endif /* __DRIVERS_THERMAL_THERMAL_CORE_H */
|
@ -758,6 +758,24 @@
|
|||||||
# define spiinfo _none
|
# define spiinfo _none
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_THERMAL_ERROR
|
||||||
|
# define therr _err
|
||||||
|
#else
|
||||||
|
# define therr _none
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_THERMAL_WARN
|
||||||
|
# define thwarn _warn
|
||||||
|
#else
|
||||||
|
# define thwarn _none
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_THERMAL_INFO
|
||||||
|
# define thinfo _info
|
||||||
|
#else
|
||||||
|
# define thinfo _none
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_TIMER_ERROR
|
#ifdef CONFIG_DEBUG_TIMER_ERROR
|
||||||
# define tmrerr _err
|
# define tmrerr _err
|
||||||
#else
|
#else
|
||||||
|
205
include/nuttx/thermal.h
Normal file
205
include/nuttx/thermal.h
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* include/nuttx/thermal.h
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __INCLUDE_NUTTX_THERMAL_H
|
||||||
|
#define __INCLUDE_NUTTX_THERMAL_H
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/list.h>
|
||||||
|
#include <nuttx/mutex.h>
|
||||||
|
#include <nuttx/wqueue.h>
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* Generic */
|
||||||
|
|
||||||
|
#define THERMAL_NAME_LEN 32
|
||||||
|
|
||||||
|
/* Trips */
|
||||||
|
|
||||||
|
#define THERMAL_NO_LIMIT 0
|
||||||
|
|
||||||
|
/* Temperature */
|
||||||
|
|
||||||
|
#define THERMAL_INVALID_TEMP INT_MIN
|
||||||
|
|
||||||
|
/* Cooling State */
|
||||||
|
|
||||||
|
#define THERMAL_TARGET_MIN 0
|
||||||
|
#define THERMAL_TARGET_MAX (UINT_MAX - 1)
|
||||||
|
#define THERMAL_NO_TARGET UINT_MAX
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
struct thermal_cooling_device_ops_s;
|
||||||
|
struct thermal_zone_device_ops_s;
|
||||||
|
struct thermal_zone_device_s;
|
||||||
|
struct thermal_zone_params_s;
|
||||||
|
|
||||||
|
enum thermal_trend_e
|
||||||
|
{
|
||||||
|
THERMAL_TREND_RAISING,
|
||||||
|
THERMAL_TREND_DROPPING,
|
||||||
|
THERMAL_TREND_STABLE,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum thermal_trip_type_e
|
||||||
|
{
|
||||||
|
THERMAL_COLD,
|
||||||
|
THERMAL_NORMAL,
|
||||||
|
THERMAL_HOT,
|
||||||
|
THERMAL_CRITICAL,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct thermal_governor_s
|
||||||
|
{
|
||||||
|
struct list_node node;
|
||||||
|
|
||||||
|
FAR const char *name;
|
||||||
|
|
||||||
|
CODE int (*bind_to_tz) (FAR struct thermal_zone_device_s *zdev);
|
||||||
|
CODE int (*throttle) (FAR struct thermal_zone_device_s *zdev,
|
||||||
|
int trip);
|
||||||
|
CODE void (*unbind_from_tz)(FAR struct thermal_zone_device_s *zdev);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct thermal_cooling_device_s
|
||||||
|
{
|
||||||
|
struct list_node node;
|
||||||
|
|
||||||
|
char name[THERMAL_NAME_LEN];
|
||||||
|
FAR void *devdata;
|
||||||
|
FAR const struct thermal_cooling_device_ops_s *ops;
|
||||||
|
|
||||||
|
struct list_node instance_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct thermal_zone_device_s
|
||||||
|
{
|
||||||
|
struct list_node node;
|
||||||
|
|
||||||
|
char name[THERMAL_NAME_LEN];
|
||||||
|
bool enabled;
|
||||||
|
|
||||||
|
FAR void *devdata;
|
||||||
|
|
||||||
|
int last_temperature;
|
||||||
|
int temperature;
|
||||||
|
|
||||||
|
FAR const struct thermal_zone_device_ops_s *ops;
|
||||||
|
FAR struct thermal_governor_s *governor;
|
||||||
|
|
||||||
|
FAR const struct thermal_zone_params_s *params;
|
||||||
|
struct work_s monitor;
|
||||||
|
|
||||||
|
struct list_node instance_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct thermal_cooling_device_ops_s
|
||||||
|
{
|
||||||
|
CODE int (*set_state) (FAR struct thermal_cooling_device_s *cdev,
|
||||||
|
unsigned int state);
|
||||||
|
CODE int (*get_state) (FAR struct thermal_cooling_device_s *cdev,
|
||||||
|
FAR unsigned int *state);
|
||||||
|
CODE int (*get_max_state)(FAR struct thermal_cooling_device_s *cdev,
|
||||||
|
FAR unsigned int *state);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct thermal_zone_device_ops_s
|
||||||
|
{
|
||||||
|
CODE int (*get_temp) (FAR struct thermal_zone_device_s *zdev,
|
||||||
|
FAR int *temp);
|
||||||
|
CODE int (*get_trend) (FAR struct thermal_zone_device_s *zdev,
|
||||||
|
FAR enum thermal_trend_e *trend);
|
||||||
|
CODE int (*set_trips) (FAR struct thermal_zone_device_s *zdev,
|
||||||
|
int low, int high);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct thermal_zone_map_s
|
||||||
|
{
|
||||||
|
FAR const char *trip_name;
|
||||||
|
|
||||||
|
FAR const char *cdev_name;
|
||||||
|
unsigned int low;
|
||||||
|
unsigned int high;
|
||||||
|
|
||||||
|
unsigned int weight;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct thermal_zone_trip_s
|
||||||
|
{
|
||||||
|
FAR const char *name;
|
||||||
|
unsigned int temp;
|
||||||
|
unsigned int hyst;
|
||||||
|
enum thermal_trip_type_e type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct thermal_zone_params_s
|
||||||
|
{
|
||||||
|
FAR const char *gov_name;
|
||||||
|
int polling_delay;
|
||||||
|
FAR const struct thermal_zone_trip_s *trips;
|
||||||
|
int num_trips;
|
||||||
|
FAR const struct thermal_zone_map_s *maps;
|
||||||
|
int num_maps;
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Function Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* Governor */
|
||||||
|
|
||||||
|
int thermal_register_governor (FAR struct thermal_governor_s *gov);
|
||||||
|
void thermal_unregister_governor(FAR struct thermal_governor_s *gov);
|
||||||
|
|
||||||
|
/* Cooling Device */
|
||||||
|
|
||||||
|
FAR struct thermal_cooling_device_s *
|
||||||
|
thermal_cooling_device_register(FAR const char *name, void *devdata,
|
||||||
|
FAR const struct thermal_cooling_device_ops_s *ops);
|
||||||
|
void
|
||||||
|
thermal_cooling_device_unregister(
|
||||||
|
FAR struct thermal_cooling_device_s *cdev);
|
||||||
|
|
||||||
|
/* Zone Device */
|
||||||
|
|
||||||
|
FAR struct thermal_zone_device_s *
|
||||||
|
thermal_zone_device_register(FAR const char *name, FAR void *devdata,
|
||||||
|
FAR const struct thermal_zone_device_ops_s *ops,
|
||||||
|
FAR const struct thermal_zone_params_s *params);
|
||||||
|
void
|
||||||
|
thermal_zone_device_unregister(
|
||||||
|
FAR struct thermal_zone_device_s *zdev);
|
||||||
|
void
|
||||||
|
thermal_zone_device_update (FAR struct thermal_zone_device_s *zdev);
|
||||||
|
|
||||||
|
/* Thermal Framework initialization */
|
||||||
|
|
||||||
|
int thermal_init(void);
|
||||||
|
|
||||||
|
#endif /* __INCLUDE_NUTTX_THERMAL_H */
|
Loading…
Reference in New Issue
Block a user