sync with OpenBSD -current

This commit is contained in:
purplerain 2023-11-24 03:38:59 +00:00
parent 10cf24ada0
commit dde71458ae
Signed by: purplerain
GPG key ID: F42C07F07E2E35B7
28 changed files with 813 additions and 112 deletions

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ofw_thermal.c,v 1.7 2020/12/31 11:11:22 kettenis Exp $ */
/* $OpenBSD: ofw_thermal.c,v 1.8 2023/11/23 00:47:13 dlg Exp $ */
/*
* Copyright (c) 2019 Mark Kettenis
*
@ -15,12 +15,16 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "kstat.h"
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/stdint.h>
#include <sys/task.h>
#include <sys/timeout.h>
#include <sys/sched.h>
#include <sys/kstat.h>
#include <machine/bus.h>
@ -36,6 +40,7 @@ LIST_HEAD(, cooling_device) cooling_devices =
struct taskq *tztq;
struct trippoint {
int tp_node;
int32_t tp_temperature;
uint32_t tp_hysteresis;
int tp_type;
@ -48,6 +53,14 @@ struct trippoint {
#define THERMAL_HOT 3
#define THERMAL_CRITICAL 4
static const char *trip_types[] = {
[THERMAL_NONE] = "none",
[THERMAL_ACTIVE] = "active",
[THERMAL_PASSIVE] = "passive",
[THERMAL_HOT] = "hot",
[THERMAL_CRITICAL] = "critical",
};
struct cmap {
uint32_t *cm_cdev;
uint32_t *cm_cdevend;
@ -82,8 +95,16 @@ struct thermal_zone {
LIST_HEAD(, cdev) tz_cdevs;
int32_t tz_temperature;
struct rwlock tz_lock;
struct kstat *tz_kstat;
};
#if NKSTAT > 0
static void thermal_zone_kstat_attach(struct thermal_zone *);
static void thermal_zone_kstat_update(struct thermal_zone *);
#endif /* NKSTAT > 0 */
LIST_HEAD(, thermal_zone) thermal_zones =
LIST_HEAD_INITIALIZER(thermal_zones);
@ -324,6 +345,9 @@ thermal_zone_poll(void *arg)
out:
tz->tz_temperature = temp;
#if NKSTAT > 0
thermal_zone_kstat_update(tz);
#endif
if (tz->tz_tp && tz->tz_tp->tp_type == THERMAL_PASSIVE)
polling_delay = tz->tz_polling_delay_passive;
else
@ -331,6 +355,23 @@ out:
timeout_add_msec(&tz->tz_poll_to, polling_delay);
}
static int
thermal_zone_triptype(const char *prop)
{
size_t i;
for (i = 0; i < nitems(trip_types); i++) {
const char *name = trip_types[i];
if (name == NULL)
continue;
if (strcmp(name, prop) == 0)
return (i);
}
return (THERMAL_NONE);
}
void
thermal_zone_init(int node)
{
@ -351,6 +392,7 @@ thermal_zone_init(int node)
tz = malloc(sizeof(struct thermal_zone), M_DEVBUF, M_ZERO | M_WAITOK);
tz->tz_node = node;
rw_init(&tz->tz_lock, "tzlk");
OF_getprop(node, "name", &tz->tz_name, sizeof(tz->tz_name));
tz->tz_name[sizeof(tz->tz_name) - 1] = 0;
@ -394,17 +436,11 @@ thermal_zone_init(int node)
break;
}
tp = &tz->tz_trips[i];
tp->tp_node = node;
tp->tp_temperature = temp;
tp->tp_hysteresis = OF_getpropint(node, "hysteresis", 0);
OF_getprop(node, "type", type, sizeof(type));
if (strcmp(type, "active") == 0)
tp->tp_type = THERMAL_ACTIVE;
else if (strcmp(type, "passive") == 0)
tp->tp_type = THERMAL_PASSIVE;
else if (strcmp(type, "hot") == 0)
tp->tp_type = THERMAL_HOT;
else if (strcmp(type, "critical") == 0)
tp->tp_type = THERMAL_CRITICAL;
tp->tp_type = thermal_zone_triptype(type);
tp->tp_phandle = OF_getpropint(node, "phandle", 0);
tp++;
}
@ -465,6 +501,10 @@ thermal_zone_init(int node)
if (tz->tz_polling_delay > 0)
timeout_add_msec(&tz->tz_poll_to, tz->tz_polling_delay);
LIST_INSERT_HEAD(&thermal_zones, tz, tz_list);
#if NKSTAT > 0
thermal_zone_kstat_attach(tz);
#endif
}
void
@ -480,3 +520,109 @@ thermal_init(void)
for (node = OF_child(node); node != 0; node = OF_peer(node))
thermal_zone_init(node);
}
#if NKSTAT > 0
static const char *
thermal_zone_tripname(int type)
{
if (type >= nitems(trip_types))
return (NULL);
return (trip_types[type]);
}
struct thermal_zone_kstats {
struct kstat_kv tzk_name; /* istr could be short */
struct kstat_kv tzk_temp;
struct kstat_kv tzk_tp;
struct kstat_kv tzk_tp_type;
struct kstat_kv tzk_cooling;
};
static void
thermal_zone_kstat_update(struct thermal_zone *tz)
{
struct kstat *ks = tz->tz_kstat;
struct thermal_zone_kstats *tzk;
if (ks == NULL)
return;
tzk = ks->ks_data;
rw_enter_write(&tz->tz_lock);
if (tz->tz_temperature == THERMAL_SENSOR_MAX)
tzk->tzk_temp.kv_type = KSTAT_KV_T_NULL;
else {
tzk->tzk_temp.kv_type = KSTAT_KV_T_TEMP;
kstat_kv_temp(&tzk->tzk_temp) = 273150000 +
1000 * tz->tz_temperature;
}
if (tz->tz_tp == NULL) {
kstat_kv_u32(&tzk->tzk_tp) = 0;
strlcpy(kstat_kv_istr(&tzk->tzk_tp_type), "none",
sizeof(kstat_kv_istr(&tzk->tzk_tp_type)));
} else {
int triptype = tz->tz_tp->tp_type;
const char *tripname = thermal_zone_tripname(triptype);
kstat_kv_u32(&tzk->tzk_tp) = tz->tz_tp->tp_node;
if (tripname == NULL) {
snprintf(kstat_kv_istr(&tzk->tzk_tp_type),
sizeof(kstat_kv_istr(&tzk->tzk_tp_type)),
"%u", triptype);
} else {
strlcpy(kstat_kv_istr(&tzk->tzk_tp_type), tripname,
sizeof(kstat_kv_istr(&tzk->tzk_tp_type)));
}
}
kstat_kv_bool(&tzk->tzk_cooling) = (tz->tz_cm != NULL);
getnanouptime(&ks->ks_updated);
rw_exit_write(&tz->tz_lock);
}
static void
thermal_zone_kstat_attach(struct thermal_zone *tz)
{
struct kstat *ks;
struct thermal_zone_kstats *tzk;
static unsigned int unit = 0;
ks = kstat_create("dt", 0, "thermal-zone", unit++, KSTAT_T_KV, 0);
if (ks == NULL) {
printf("unable to create thermal-zone kstats for %s",
tz->tz_name);
return;
}
tzk = malloc(sizeof(*tzk), M_DEVBUF, M_WAITOK|M_ZERO);
kstat_kv_init(&tzk->tzk_name, "name", KSTAT_KV_T_ISTR);
strlcpy(kstat_kv_istr(&tzk->tzk_name), tz->tz_name,
sizeof(kstat_kv_istr(&tzk->tzk_name)));
kstat_kv_init(&tzk->tzk_temp, "temperature", KSTAT_KV_T_NULL);
/* XXX dt node is not be the most useful info here. */
kstat_kv_init(&tzk->tzk_tp, "trip-point-node", KSTAT_KV_T_UINT32);
kstat_kv_init(&tzk->tzk_tp_type, "trip-type", KSTAT_KV_T_ISTR);
strlcpy(kstat_kv_istr(&tzk->tzk_tp_type), "unknown",
sizeof(kstat_kv_istr(&tzk->tzk_tp_type)));
kstat_kv_init(&tzk->tzk_cooling, "active-cooling", KSTAT_KV_T_BOOL);
kstat_kv_bool(&tzk->tzk_cooling) = 0;
ks->ks_softc = tz;
ks->ks_data = tzk;
ks->ks_datalen = sizeof(*tzk);
ks->ks_read = kstat_read_nop;
kstat_set_rlock(ks, &tz->tz_lock);
tz->tz_kstat = ks;
kstat_install(ks);
}
#endif /* NKSTAT > 0 */