summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Lezcano <daniel.lezcano@linaro.org>2023-06-29 13:14:54 +0200
committerDaniel Lezcano <daniel.lezcano@linaro.org>2023-06-29 13:14:54 +0200
commit136a5443698e2c7a515d9440338a0ff8d3f0b7e8 (patch)
tree76e7bc966471f4e35146e5094468814ff882e08a
parent6cf776dd8ddf5b1ec536a0d05bd7def5f6d54f6e (diff)
Reorder the files to make the component more compliantHEADmaster
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-rw-r--r--Android.bp2
-rw-r--r--include/libthermal.h128
-rw-r--r--include/thermal.h142
-rw-r--r--patches/array_size_macro.patch15
-rw-r--r--patches/patches.list1
-rw-r--r--src/Makefile2
-rw-r--r--src/commands.c178
-rw-r--r--src/events.c55
-rw-r--r--src/sampling.c35
-rw-r--r--src/thermal.c40
-rw-r--r--src/thermal_nl.c (renamed from src/netlink.c)70
-rw-r--r--src/thermal_nl.h (renamed from src/thermal.h)6
-rwxr-xr-xsync.sh51
-rw-r--r--tst/tst_thermal.c2
14 files changed, 426 insertions, 301 deletions
diff --git a/Android.bp b/Android.bp
index d29295e..17993e0 100644
--- a/Android.bp
+++ b/Android.bp
@@ -56,7 +56,7 @@ cc_library_shared {
"src/events.c",
"src/sampling.c",
"src/commands.c",
- "src/netlink.c",
+ "src/thermal_nl.c",
],
local_include_dirs: [
diff --git a/include/libthermal.h b/include/libthermal.h
deleted file mode 100644
index 17a2111..0000000
--- a/include/libthermal.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#ifndef __LIBTHERMAL_H
-#define __LIBTHERMAL_H
-
-#include <linux/thermal.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef THERMAL_NAME_LENGTH
-#define THERMAL_NAME_LENGTH 64
-#endif
-
-struct thermal_sampling_ops {
- int (*tz_temp)(int tz_id, int temp, void *arg);
-};
-
-struct thermal_events_ops {
- int (*tz_create)(const char *name, int tz_id, void *arg);
- int (*tz_delete)(int tz_id, void *arg);
- int (*tz_enable)(int tz_id, void *arg);
- int (*tz_disable)(int tz_id, void *arg);
- int (*trip_high)(int tz_id, int trip_id, int temp, void *arg);
- int (*trip_low)(int tz_id, int trip_id, int temp, void *arg);
- int (*trip_add)(int tz_id, int trip_id, int type, int temp, int hyst, void *arg);
- int (*trip_change)(int tz_id, int trip_id, int type, int temp, int hyst, void *arg);
- int (*trip_delete)(int tz_id, int trip_id, void *arg);
- int (*cdev_add)(const char *name, int cdev_id, int max_state, void *arg);
- int (*cdev_delete)(int cdev_id, void *arg);
- int (*cdev_update)(int cdev_id, int cur_state, void *arg);
- int (*gov_change)(int tz_id, const char *gov_name, void *arg);
-};
-
-struct thermal_ops {
- struct thermal_sampling_ops sampling;
- struct thermal_events_ops events;
-};
-
-struct thermal_trip {
- int id;
- int type;
- int temp;
- int hyst;
-};
-
-struct thermal_zone {
- int id;
- int temp;
- char name[THERMAL_NAME_LENGTH];
- char governor[THERMAL_NAME_LENGTH];
- struct thermal_trip *trip;
-};
-
-struct thermal_cdev {
- int id;
- char name[THERMAL_NAME_LENGTH];
- int max_state;
- int min_state;
- int cur_state;
-};
-
-struct thermal_handler;
-
-typedef int (*cb_tz_t)(struct thermal_zone *, void *);
-
-typedef int (*cb_tt_t)(struct thermal_trip *, void *);
-
-typedef int (*cb_tc_t)(struct thermal_cdev *, void *);
-
-int for_each_thermal_zone(struct thermal_zone *tz, cb_tz_t cb, void *arg);
-
-int for_each_thermal_trip(struct thermal_trip *tt, cb_tt_t cb, void *arg);
-
-int for_each_thermal_cdev(struct thermal_cdev *cdev, cb_tc_t cb, void *arg);
-
-struct thermal_zone *thermal_zone_find_by_name(struct thermal_zone *tz,
- const char *name);
-
-struct thermal_zone *thermal_zone_find_by_id(struct thermal_zone *tz, int id);
-
-struct thermal_zone *thermal_zone_discover(struct thermal_handler *th);
-
-struct thermal_handler *thermal_init(struct thermal_ops *ops);
-
-/*
- * Netlink thermal events
- */
-extern int thermal_events_init(struct thermal_handler *th);
-
-extern int thermal_events_handle(struct thermal_handler *th, void *arg);
-
-extern int thermal_events_fd(struct thermal_handler *th);
-
-/*
- * Netlink thermal commands
- */
-extern int thermal_cmd_init(struct thermal_handler *th);
-
-extern int thermal_cmd_get_tz(struct thermal_handler *th,
- struct thermal_zone **tz);
-
-extern int thermal_cmd_get_cdev(struct thermal_handler *th,
- struct thermal_cdev **tc);
-
-extern int thermal_cmd_get_trip(struct thermal_handler *th,
- struct thermal_zone *tz);
-
-extern int thermal_cmd_get_governor(struct thermal_handler *th,
- struct thermal_zone *tz);
-
-extern int thermal_cmd_get_temp(struct thermal_handler *th,
- struct thermal_zone *tz);
-
-/*
- * Netlink thermal samples
- */
-extern int thermal_sampling_init(struct thermal_handler *th);
-
-extern int thermal_sampling_handle(struct thermal_handler *th, void *arg);
-
-extern int thermal_sampling_fd(struct thermal_handler *th);
-
-#endif /* __LIBTHERMAL_H */
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/include/thermal.h b/include/thermal.h
new file mode 100644
index 0000000..1abc560
--- /dev/null
+++ b/include/thermal.h
@@ -0,0 +1,142 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+/* Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org> */
+#ifndef __LIBTHERMAL_H
+#define __LIBTHERMAL_H
+
+#include <linux/thermal.h>
+
+#ifndef LIBTHERMAL_API
+#define LIBTHERMAL_API __attribute__((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct thermal_sampling_ops {
+ int (*tz_temp)(int tz_id, int temp, void *arg);
+};
+
+struct thermal_events_ops {
+ int (*tz_create)(const char *name, int tz_id, void *arg);
+ int (*tz_delete)(int tz_id, void *arg);
+ int (*tz_enable)(int tz_id, void *arg);
+ int (*tz_disable)(int tz_id, void *arg);
+ int (*trip_high)(int tz_id, int trip_id, int temp, void *arg);
+ int (*trip_low)(int tz_id, int trip_id, int temp, void *arg);
+ int (*trip_add)(int tz_id, int trip_id, int type, int temp, int hyst, void *arg);
+ int (*trip_change)(int tz_id, int trip_id, int type, int temp, int hyst, void *arg);
+ int (*trip_delete)(int tz_id, int trip_id, void *arg);
+ int (*cdev_add)(const char *name, int cdev_id, int max_state, void *arg);
+ int (*cdev_delete)(int cdev_id, void *arg);
+ int (*cdev_update)(int cdev_id, int cur_state, void *arg);
+ int (*gov_change)(int tz_id, const char *gov_name, void *arg);
+};
+
+struct thermal_ops {
+ struct thermal_sampling_ops sampling;
+ struct thermal_events_ops events;
+};
+
+struct thermal_trip {
+ int id;
+ int type;
+ int temp;
+ int hyst;
+};
+
+struct thermal_zone {
+ int id;
+ int temp;
+ char name[THERMAL_NAME_LENGTH];
+ char governor[THERMAL_NAME_LENGTH];
+ struct thermal_trip *trip;
+};
+
+struct thermal_cdev {
+ int id;
+ char name[THERMAL_NAME_LENGTH];
+ int max_state;
+ int min_state;
+ int cur_state;
+};
+
+typedef enum {
+ THERMAL_ERROR = -1,
+ THERMAL_SUCCESS = 0,
+} thermal_error_t;
+
+struct thermal_handler;
+
+typedef int (*cb_tz_t)(struct thermal_zone *, void *);
+
+typedef int (*cb_tt_t)(struct thermal_trip *, void *);
+
+typedef int (*cb_tc_t)(struct thermal_cdev *, void *);
+
+LIBTHERMAL_API int for_each_thermal_zone(struct thermal_zone *tz, cb_tz_t cb, void *arg);
+
+LIBTHERMAL_API int for_each_thermal_trip(struct thermal_trip *tt, cb_tt_t cb, void *arg);
+
+LIBTHERMAL_API int for_each_thermal_cdev(struct thermal_cdev *cdev, cb_tc_t cb, void *arg);
+
+LIBTHERMAL_API struct thermal_zone *thermal_zone_find_by_name(struct thermal_zone *tz,
+ const char *name);
+
+LIBTHERMAL_API struct thermal_zone *thermal_zone_find_by_id(struct thermal_zone *tz, int id);
+
+LIBTHERMAL_API struct thermal_zone *thermal_zone_discover(struct thermal_handler *th);
+
+LIBTHERMAL_API struct thermal_handler *thermal_init(struct thermal_ops *ops);
+
+LIBTHERMAL_API void thermal_exit(struct thermal_handler *th);
+
+/*
+ * Netlink thermal events
+ */
+LIBTHERMAL_API thermal_error_t thermal_events_exit(struct thermal_handler *th);
+
+LIBTHERMAL_API thermal_error_t thermal_events_init(struct thermal_handler *th);
+
+LIBTHERMAL_API thermal_error_t thermal_events_handle(struct thermal_handler *th, void *arg);
+
+LIBTHERMAL_API int thermal_events_fd(struct thermal_handler *th);
+
+/*
+ * Netlink thermal commands
+ */
+LIBTHERMAL_API thermal_error_t thermal_cmd_exit(struct thermal_handler *th);
+
+LIBTHERMAL_API thermal_error_t thermal_cmd_init(struct thermal_handler *th);
+
+LIBTHERMAL_API thermal_error_t thermal_cmd_get_tz(struct thermal_handler *th,
+ struct thermal_zone **tz);
+
+LIBTHERMAL_API thermal_error_t thermal_cmd_get_cdev(struct thermal_handler *th,
+ struct thermal_cdev **tc);
+
+LIBTHERMAL_API thermal_error_t thermal_cmd_get_trip(struct thermal_handler *th,
+ struct thermal_zone *tz);
+
+LIBTHERMAL_API thermal_error_t thermal_cmd_get_governor(struct thermal_handler *th,
+ struct thermal_zone *tz);
+
+LIBTHERMAL_API thermal_error_t thermal_cmd_get_temp(struct thermal_handler *th,
+ struct thermal_zone *tz);
+
+/*
+ * Netlink thermal samples
+ */
+LIBTHERMAL_API thermal_error_t thermal_sampling_exit(struct thermal_handler *th);
+
+LIBTHERMAL_API thermal_error_t thermal_sampling_init(struct thermal_handler *th);
+
+LIBTHERMAL_API thermal_error_t thermal_sampling_handle(struct thermal_handler *th, void *arg);
+
+LIBTHERMAL_API int thermal_sampling_fd(struct thermal_handler *th);
+
+#endif /* __LIBTHERMAL_H */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/patches/array_size_macro.patch b/patches/array_size_macro.patch
new file mode 100644
index 0000000..f18b1f5
--- /dev/null
+++ b/patches/array_size_macro.patch
@@ -0,0 +1,15 @@
+diff --git a/src/commands.c b/src/commands.c
+index 73d4d4e8d6ec..f57db6d07615 100644
+--- a/src/commands.c
++++ b/src/commands.c
+@@ -9,6 +9,10 @@
+ #include <thermal.h>
+ #include "thermal_nl.h"
+
++#ifndef ARRAY_SIZE
++#define ARRAY_SIZE(__array) (sizeof(__array) / sizeof(__array[0]))
++#endif
++
+ static struct nla_policy thermal_genl_policy[THERMAL_GENL_ATTR_MAX + 1] = {
+ /* Thermal zone */
+ [THERMAL_GENL_ATTR_TZ] = { .type = NLA_NESTED },
diff --git a/patches/patches.list b/patches/patches.list
new file mode 100644
index 0000000..6f28588
--- /dev/null
+++ b/patches/patches.list
@@ -0,0 +1 @@
+array_size_macro.patch
diff --git a/src/Makefile b/src/Makefile
index eb9db6a..7f8610a 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -3,7 +3,7 @@ CC=gcc
CFLAGS+=-g -Wall -Wno-unused -I/usr/include/libnl3 -I../include -fPIC -Wextra -O2
LDFLAGS=-lnl-genl-3 -lnl-3 -shared
DEPS = include/libthermal.h
-OBJS = thermal.o events.o sampling.o commands.o netlink.o
+OBJS = thermal.o events.o sampling.o commands.o thermal_nl.o
LIB=libthermal.so
BINS=$(C_BINS:.c=)
diff --git a/src/commands.c b/src/commands.c
index 4a7bc22..f57db6d 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -1,11 +1,17 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+// SPDX-License-Identifier: LGPL-2.1+
+// Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org>
#define _GNU_SOURCE
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#include "thermal.h"
+#include <thermal.h>
+#include "thermal_nl.h"
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(__array) (sizeof(__array) / sizeof(__array[0]))
+#endif
static struct nla_policy thermal_genl_policy[THERMAL_GENL_ATTR_MAX + 1] = {
/* Thermal zone */
@@ -47,10 +53,8 @@ static int parse_tz_get(struct genl_info *info, struct thermal_zone **tz)
size++;
__tz = realloc(__tz, sizeof(*__tz) * (size + 2));
- if (!__tz) {
- fprintf(stderr, "Failed to allocate memory\n");
- return -1;
- }
+ if (!__tz)
+ return THERMAL_ERROR;
__tz[size - 1].id = nla_get_u32(attr);
}
@@ -61,17 +65,15 @@ static int parse_tz_get(struct genl_info *info, struct thermal_zone **tz)
THERMAL_NAME_LENGTH);
}
- /*
- * We end the array of thermal zones
- */
- __tz[size].id = -1;
+ if (__tz)
+ __tz[size].id = -1;
*tz = __tz;
- return 0;
+ return THERMAL_SUCCESS;
}
-int parse_cdev_get(struct genl_info *info, struct thermal_cdev **cdev)
+static int parse_cdev_get(struct genl_info *info, struct thermal_cdev **cdev)
{
struct nlattr *attr;
struct thermal_cdev *__cdev = NULL;
@@ -85,10 +87,8 @@ int parse_cdev_get(struct genl_info *info, struct thermal_cdev **cdev)
size++;
__cdev = realloc(__cdev, sizeof(*__cdev) * (size + 2));
- if (!__cdev) {
- fprintf(stderr, "Failed to allocate memory\n");
- return -1;
- }
+ if (!__cdev)
+ return THERMAL_ERROR;
__cdev[size - 1].id = nla_get_u32(attr);
}
@@ -98,20 +98,19 @@ int parse_cdev_get(struct genl_info *info, struct thermal_cdev **cdev)
THERMAL_NAME_LENGTH);
}
- if (nla_type(attr) == THERMAL_GENL_ATTR_CDEV_CUR_STATE) {
+ if (nla_type(attr) == THERMAL_GENL_ATTR_CDEV_CUR_STATE)
__cdev[size - 1].cur_state = nla_get_u32(attr);
- }
- if (nla_type(attr) == THERMAL_GENL_ATTR_CDEV_MAX_STATE) {
+ if (nla_type(attr) == THERMAL_GENL_ATTR_CDEV_MAX_STATE)
__cdev[size - 1].max_state = nla_get_u32(attr);
- }
}
- __cdev[size].id = -1;
+ if (__cdev)
+ __cdev[size].id = -1;
*cdev = __cdev;
- return 0;
+ return THERMAL_SUCCESS;
}
static int parse_tz_get_trip(struct genl_info *info, struct thermal_zone *tz)
@@ -128,10 +127,8 @@ static int parse_tz_get_trip(struct genl_info *info, struct thermal_zone *tz)
size++;
__tt = realloc(__tt, sizeof(*__tt) * (size + 2));
- if (!__tt) {
- fprintf(stderr, "Failed to allocate memory\n");
- return -1;
- }
+ if (!__tt)
+ return THERMAL_ERROR;
__tt[size - 1].id = nla_get_u32(attr);
}
@@ -146,11 +143,12 @@ static int parse_tz_get_trip(struct genl_info *info, struct thermal_zone *tz)
__tt[size - 1].hyst = nla_get_u32(attr);
}
- __tt[size].id = -1;
+ if (__tt)
+ __tt[size].id = -1;
tz->trip = __tt;
- return 0;
+ return THERMAL_SUCCESS;
}
static int parse_tz_get_temp(struct genl_info *info, struct thermal_zone *tz)
@@ -160,16 +158,13 @@ static int parse_tz_get_temp(struct genl_info *info, struct thermal_zone *tz)
if (info->attrs[THERMAL_GENL_ATTR_TZ_ID])
id = nla_get_u32(info->attrs[THERMAL_GENL_ATTR_TZ_ID]);
- if (tz->id != id) {
- fprintf(stderr, "thermal zone id mismatch '%d' <> '%d'\n",
- tz->id, id);
- return -1;
- }
+ if (tz->id != id)
+ return THERMAL_ERROR;
if (info->attrs[THERMAL_GENL_ATTR_TZ_TEMP])
tz->temp = nla_get_u32(info->attrs[THERMAL_GENL_ATTR_TZ_TEMP]);
- return 0;
+ return THERMAL_SUCCESS;
}
static int parse_tz_get_gov(struct genl_info *info, struct thermal_zone *tz)
@@ -179,11 +174,8 @@ static int parse_tz_get_gov(struct genl_info *info, struct thermal_zone *tz)
if (info->attrs[THERMAL_GENL_ATTR_TZ_ID])
id = nla_get_u32(info->attrs[THERMAL_GENL_ATTR_TZ_ID]);
- if (tz->id != id) {
- fprintf(stderr, "thermal zone id mismatch '%d' <> '%d'\n",
- tz->id, id);
- return -1;
- }
+ if (tz->id != id)
+ return THERMAL_ERROR;
if (info->attrs[THERMAL_GENL_ATTR_TZ_GOV_NAME]) {
nla_strlcpy(tz->governor,
@@ -191,175 +183,171 @@ static int parse_tz_get_gov(struct genl_info *info, struct thermal_zone *tz)
THERMAL_NAME_LENGTH);
}
- return 0;
+ return THERMAL_SUCCESS;
}
static int handle_netlink(struct nl_cache_ops *unused,
struct genl_cmd *cmd,
struct genl_info *info, void *arg)
{
+ int ret;
+
switch (cmd->c_id) {
case THERMAL_GENL_CMD_TZ_GET_ID:
- parse_tz_get(info, arg);
+ ret = parse_tz_get(info, arg);
break;
case THERMAL_GENL_CMD_CDEV_GET:
- parse_cdev_get(info, arg);
+ ret = parse_cdev_get(info, arg);
break;
case THERMAL_GENL_CMD_TZ_GET_TEMP:
- parse_tz_get_temp(info, arg);
+ ret = parse_tz_get_temp(info, arg);
break;
case THERMAL_GENL_CMD_TZ_GET_TRIP:
- parse_tz_get_trip(info, arg);
+ ret = parse_tz_get_trip(info, arg);
break;
case THERMAL_GENL_CMD_TZ_GET_GOV:
- parse_tz_get_gov(info, arg);
+ ret = parse_tz_get_gov(info, arg);
break;
default:
- printf("Unknown command id:%d\n", cmd->c_id);
- };
+ return THERMAL_ERROR;
+ }
- return 0;
+ return ret;
}
static struct genl_cmd thermal_cmds[] = {
{
.c_id = THERMAL_GENL_CMD_TZ_GET_ID,
- .c_name = "List thermal zones",
+ .c_name = (char *)"List thermal zones",
.c_msg_parser = handle_netlink,
.c_maxattr = THERMAL_GENL_ATTR_MAX,
.c_attr_policy = thermal_genl_policy,
},
{
.c_id = THERMAL_GENL_CMD_TZ_GET_GOV,
- .c_name = "Get governor",
+ .c_name = (char *)"Get governor",
.c_msg_parser = handle_netlink,
.c_maxattr = THERMAL_GENL_ATTR_MAX,
.c_attr_policy = thermal_genl_policy,
},
{
.c_id = THERMAL_GENL_CMD_TZ_GET_TEMP,
- .c_name = "Get thermal zone temperature",
+ .c_name = (char *)"Get thermal zone temperature",
.c_msg_parser = handle_netlink,
.c_maxattr = THERMAL_GENL_ATTR_MAX,
.c_attr_policy = thermal_genl_policy,
},
{
.c_id = THERMAL_GENL_CMD_TZ_GET_TRIP,
- .c_name = "Get thermal zone trip points",
+ .c_name = (char *)"Get thermal zone trip points",
.c_msg_parser = handle_netlink,
.c_maxattr = THERMAL_GENL_ATTR_MAX,
.c_attr_policy = thermal_genl_policy,
},
{
.c_id = THERMAL_GENL_CMD_CDEV_GET,
- .c_name = "Get cooling devices",
+ .c_name = (char *)"Get cooling devices",
.c_msg_parser = handle_netlink,
.c_maxattr = THERMAL_GENL_ATTR_MAX,
.c_attr_policy = thermal_genl_policy,
},
};
-#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
-
static struct genl_ops thermal_cmd_ops = {
- .o_name = "thermal",
+ .o_name = (char *)"thermal",
.o_cmds = thermal_cmds,
.o_ncmds = ARRAY_SIZE(thermal_cmds),
};
-static int thermal_genl_auto(struct thermal_handler *th, int id, int cmd,
- int flags, void *arg)
+static thermal_error_t thermal_genl_auto(struct thermal_handler *th, int id, int cmd,
+ int flags, void *arg)
{
struct nl_msg *msg;
void *hdr;
msg = nlmsg_alloc();
- if (!msg) {
- fprintf(stderr, "Failed to allocate message\n");
- return -1;
- }
+ if (!msg)
+ return THERMAL_ERROR;
hdr = genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, thermal_cmd_ops.o_id,
0, flags, cmd, THERMAL_GENL_VERSION);
- if (!hdr) {
- fprintf(stderr, "Failed to set message\n");
- return -1;
- }
+ if (!hdr)
+ return THERMAL_ERROR;
- if (id >= 0 && nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_ID, id)) {
- fprintf(stderr, "Failed to set tz id\n");
- return -1;
- }
+ if (id >= 0 && nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_ID, id))
+ return THERMAL_ERROR;
- if (nl_send_msg(th->sk_cmd, th->cb_cmd, msg, genl_handle_msg, arg)) {
- fprintf(stderr, "Failed to send command\n");
- return -1;
- }
+ if (nl_send_msg(th->sk_cmd, th->cb_cmd, msg, genl_handle_msg, arg))
+ return THERMAL_ERROR;
nlmsg_free(msg);
- return 0;
+ return THERMAL_SUCCESS;
}
-int thermal_cmd_get_tz(struct thermal_handler *th, struct thermal_zone **tz)
+thermal_error_t thermal_cmd_get_tz(struct thermal_handler *th, struct thermal_zone **tz)
{
return thermal_genl_auto(th, -1, THERMAL_GENL_CMD_TZ_GET_ID,
NLM_F_DUMP | NLM_F_ACK, tz);
}
-int thermal_cmd_get_cdev(struct thermal_handler *th, struct thermal_cdev **tc)
+thermal_error_t thermal_cmd_get_cdev(struct thermal_handler *th, struct thermal_cdev **tc)
{
return thermal_genl_auto(th, -1, THERMAL_GENL_CMD_CDEV_GET,
NLM_F_DUMP | NLM_F_ACK, tc);
}
-int thermal_cmd_get_trip(struct thermal_handler *th, struct thermal_zone *tz)
+thermal_error_t thermal_cmd_get_trip(struct thermal_handler *th, struct thermal_zone *tz)
{
return thermal_genl_auto(th, tz->id, THERMAL_GENL_CMD_TZ_GET_TRIP,
0, tz);
}
-int thermal_cmd_get_governor(struct thermal_handler *th, struct thermal_zone *tz)
+thermal_error_t thermal_cmd_get_governor(struct thermal_handler *th, struct thermal_zone *tz)
{
return thermal_genl_auto(th, tz->id, THERMAL_GENL_CMD_TZ_GET_GOV, 0, tz);
}
-int thermal_cmd_get_temp(struct thermal_handler *th, struct thermal_zone *tz)
+thermal_error_t thermal_cmd_get_temp(struct thermal_handler *th, struct thermal_zone *tz)
{
return thermal_genl_auto(th, tz->id, THERMAL_GENL_CMD_TZ_GET_TEMP, 0, tz);
}
-int thermal_cmd_init(struct thermal_handler *th)
+thermal_error_t thermal_cmd_exit(struct thermal_handler *th)
+{
+ if (genl_unregister_family(&thermal_cmd_ops))
+ return THERMAL_ERROR;
+
+ nl_thermal_disconnect(th->sk_cmd, th->cb_cmd);
+
+ return THERMAL_SUCCESS;
+}
+
+thermal_error_t thermal_cmd_init(struct thermal_handler *th)
{
int ret;
int family;
if (nl_thermal_connect(&th->sk_cmd, &th->cb_cmd))
- return -1;
+ return THERMAL_ERROR;
ret = genl_register_family(&thermal_cmd_ops);
- if (ret) {
- fprintf(stderr, "genl_register_family: %d\n", ret);
- return -1;
- }
+ if (ret)
+ return THERMAL_ERROR;
ret = genl_ops_resolve(th->sk_cmd, &thermal_cmd_ops);
- if (ret) {
- fprintf(stderr, "genl_ops_resolve: %d\n", ret);
- return -1;
- }
+ if (ret)
+ return THERMAL_ERROR;
family = genl_ctrl_resolve(th->sk_cmd, "nlctrl");
- if (family != GENL_ID_CTRL) {
- fprintf(stderr, "genl_ctrl_resolve: %d\n", family);
- return -1;
- }
+ if (family != GENL_ID_CTRL)
+ return THERMAL_ERROR;
- return 0;
+ return THERMAL_SUCCESS;
}
diff --git a/src/events.c b/src/events.c
index eb49a3c..a7a55d1 100644
--- a/src/events.c
+++ b/src/events.c
@@ -1,10 +1,13 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#include <errno.h>
+// SPDX-License-Identifier: LGPL-2.1+
+// Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org>
+#include <linux/netlink.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#include "thermal.h"
+
+#include <thermal.h>
+#include "thermal_nl.h"
/*
* Optimization: fill this array to tell which event we do want to pay
@@ -13,7 +16,7 @@
* will be able to discard the event if there is not ops associated
* with it.
*/
-static int enabled_ops[ __THERMAL_GENL_EVENT_MAX];
+static int enabled_ops[__THERMAL_GENL_EVENT_MAX];
static int handle_thermal_event(struct nl_msg *n, void *arg)
{
@@ -31,7 +34,7 @@ static int handle_thermal_event(struct nl_msg *n, void *arg)
* This is an event we don't care of, bail out.
*/
if (!enabled_ops[genlhdr->cmd])
- return 0;
+ return THERMAL_SUCCESS;
switch (genlhdr->cmd) {
@@ -67,19 +70,14 @@ static int handle_thermal_event(struct nl_msg *n, void *arg)
nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID]), arg);
case THERMAL_GENL_EVENT_TZ_TRIP_UP:
-/* return th->ops->trip_high(nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]),
- nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID]),
- nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TEMP])); */
return ops->trip_high(nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]),
- nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID]), -1, arg);
-
+ nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID]),
+ nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TEMP]), arg);
case THERMAL_GENL_EVENT_TZ_TRIP_DOWN:
- /* return th->ops->trip_low(nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]), */
- /* nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID]), */
- /* nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TEMP])); */
return ops->trip_low(nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]),
- nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID]), -1, arg);
+ nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID]),
+ nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TEMP]), arg);
case THERMAL_GENL_EVENT_CDEV_ADD:
return ops->cdev_add(nla_get_string(attrs[THERMAL_GENL_ATTR_CDEV_NAME]),
@@ -96,9 +94,9 @@ static int handle_thermal_event(struct nl_msg *n, void *arg)
case THERMAL_GENL_EVENT_TZ_GOV_CHANGE:
return ops->gov_change(nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]),
nla_get_string(attrs[THERMAL_GENL_ATTR_GOV_NAME]), arg);
+ default:
+ return -1;
}
-
- return -1;
}
static void thermal_events_ops_init(struct thermal_events_ops *ops)
@@ -118,16 +116,16 @@ static void thermal_events_ops_init(struct thermal_events_ops *ops)
enabled_ops[THERMAL_GENL_EVENT_TZ_GOV_CHANGE] = !!ops->gov_change;
}
-int thermal_events_handle(struct thermal_handler *th, void *arg)
+thermal_error_t thermal_events_handle(struct thermal_handler *th, void *arg)
{
struct thermal_handler_param thp = { .th = th, .arg = arg };
if (!th)
- return -1;
+ return THERMAL_ERROR;
if (nl_cb_set(th->cb_event, NL_CB_VALID, NL_CB_CUSTOM,
handle_thermal_event, &thp))
- return -1;
+ return THERMAL_ERROR;
return nl_recvmsgs(th->sk_event, th->cb_event);
}
@@ -140,16 +138,27 @@ int thermal_events_fd(struct thermal_handler *th)
return nl_socket_get_fd(th->sk_event);
}
-int thermal_events_init(struct thermal_handler *th)
+thermal_error_t thermal_events_exit(struct thermal_handler *th)
+{
+ if (nl_unsubscribe_thermal(th->sk_event, th->cb_event,
+ THERMAL_GENL_EVENT_GROUP_NAME))
+ return THERMAL_ERROR;
+
+ nl_thermal_disconnect(th->sk_event, th->cb_event);
+
+ return THERMAL_SUCCESS;
+}
+
+thermal_error_t thermal_events_init(struct thermal_handler *th)
{
thermal_events_ops_init(&th->ops->events);
if (nl_thermal_connect(&th->sk_event, &th->cb_event))
- return -1;
+ return THERMAL_ERROR;
if (nl_subscribe_thermal(th->sk_event, th->cb_event,
THERMAL_GENL_EVENT_GROUP_NAME))
- return -1;
+ return THERMAL_ERROR;
- return 0;
+ return THERMAL_SUCCESS;
}
diff --git a/src/sampling.c b/src/sampling.c
index 3609555..7057742 100644
--- a/src/sampling.c
+++ b/src/sampling.c
@@ -1,10 +1,12 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+// SPDX-License-Identifier: LGPL-2.1+
+// Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#include "thermal.h"
+#include <thermal.h>
+#include "thermal_nl.h"
static int handle_thermal_sample(struct nl_msg *n, void *arg)
{
@@ -22,21 +24,21 @@ static int handle_thermal_sample(struct nl_msg *n, void *arg)
return th->ops->sampling.tz_temp(
nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]),
nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TEMP]), arg);
+ default:
+ return THERMAL_ERROR;
}
-
- return -1;
}
-int thermal_sampling_handle(struct thermal_handler *th, void *arg)
+thermal_error_t thermal_sampling_handle(struct thermal_handler *th, void *arg)
{
struct thermal_handler_param thp = { .th = th, .arg = arg };
if (!th)
- return -1;
+ return THERMAL_ERROR;
if (nl_cb_set(th->cb_sampling, NL_CB_VALID, NL_CB_CUSTOM,
handle_thermal_sample, &thp))
- return -1;
+ return THERMAL_ERROR;
return nl_recvmsgs(th->sk_sampling, th->cb_sampling);
}
@@ -49,14 +51,25 @@ int thermal_sampling_fd(struct thermal_handler *th)
return nl_socket_get_fd(th->sk_sampling);
}
-int thermal_sampling_init(struct thermal_handler *th)
+thermal_error_t thermal_sampling_exit(struct thermal_handler *th)
+{
+ if (nl_unsubscribe_thermal(th->sk_sampling, th->cb_sampling,
+ THERMAL_GENL_SAMPLING_GROUP_NAME))
+ return THERMAL_ERROR;
+
+ nl_thermal_disconnect(th->sk_sampling, th->cb_sampling);
+
+ return THERMAL_SUCCESS;
+}
+
+thermal_error_t thermal_sampling_init(struct thermal_handler *th)
{
if (nl_thermal_connect(&th->sk_sampling, &th->cb_sampling))
- return -1;
+ return THERMAL_ERROR;
if (nl_subscribe_thermal(th->sk_sampling, th->cb_sampling,
THERMAL_GENL_SAMPLING_GROUP_NAME))
- return -1;
+ return THERMAL_ERROR;
- return 0;
+ return THERMAL_SUCCESS;
}
diff --git a/src/thermal.c b/src/thermal.c
index bf121b9..72a76dc 100644
--- a/src/thermal.c
+++ b/src/thermal.c
@@ -1,20 +1,30 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#include "thermal.h"
+// SPDX-License-Identifier: LGPL-2.1+
+// Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org>
+#include <stdio.h>
+#include <thermal.h>
+
+#include "thermal_nl.h"
int for_each_thermal_cdev(struct thermal_cdev *cdev, cb_tc_t cb, void *arg)
{
int i, ret = 0;
+ if (!cdev)
+ return 0;
+
for (i = 0; cdev[i].id != -1; i++)
ret |= cb(&cdev[i], arg);
return ret;
-}
+}
int for_each_thermal_trip(struct thermal_trip *tt, cb_tt_t cb, void *arg)
{
int i, ret = 0;
+ if (!tt)
+ return 0;
+
for (i = 0; tt[i].id != -1; i++)
ret |= cb(&tt[i], arg);
@@ -25,6 +35,9 @@ int for_each_thermal_zone(struct thermal_zone *tz, cb_tz_t cb, void *arg)
{
int i, ret = 0;
+ if (!tz)
+ return 0;
+
for (i = 0; tz[i].id != -1; i++)
ret |= cb(&tz[i], arg);
@@ -36,9 +49,9 @@ struct thermal_zone *thermal_zone_find_by_name(struct thermal_zone *tz,
{
int i;
- if (!name)
+ if (!tz || !name)
return NULL;
-
+
for (i = 0; tz[i].id != -1; i++) {
if (!strcmp(tz[i].name, name))
return &tz[i];
@@ -51,9 +64,9 @@ struct thermal_zone *thermal_zone_find_by_id(struct thermal_zone *tz, int id)
{
int i;
- if (id < 0)
+ if (!tz || id < 0)
return NULL;
-
+
for (i = 0; tz[i].id != -1; i++) {
if (tz[i].id == id)
return &tz[i];
@@ -86,6 +99,15 @@ struct thermal_zone *thermal_zone_discover(struct thermal_handler *th)
return tz;
}
+void thermal_exit(struct thermal_handler *th)
+{
+ thermal_cmd_exit(th);
+ thermal_events_exit(th);
+ thermal_sampling_exit(th);
+
+ free(th);
+}
+
struct thermal_handler *thermal_init(struct thermal_ops *ops)
{
struct thermal_handler *th;
@@ -103,11 +125,11 @@ struct thermal_handler *thermal_init(struct thermal_ops *ops)
if (thermal_cmd_init(th))
goto out_free;
-
+
return th;
out_free:
free(th);
-
+
return NULL;
}
diff --git a/src/netlink.c b/src/thermal_nl.c
index 9ebb7e2..b05cf95 100644
--- a/src/netlink.c
+++ b/src/thermal_nl.c
@@ -1,12 +1,12 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+// SPDX-License-Identifier: LGPL-2.1+
+// Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#include <sys/epoll.h>
-
-#include "thermal.h"
+#include <thermal.h>
+#include "thermal_nl.h"
struct handler_args {
const char *group;
@@ -56,13 +56,11 @@ int nl_send_msg(struct nl_sock *sock, struct nl_cb *cb, struct nl_msg *msg,
int (*rx_handler)(struct nl_msg *, void *), void *data)
{
if (!rx_handler)
- return -1;
+ return THERMAL_ERROR;
err = nl_send_auto_complete(sock, msg);
- if (err < 0) {
- fprintf(stderr, "auto complete failed\n");
+ if (err < 0)
return err;
- }
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, rx_handler, data);
@@ -85,10 +83,8 @@ static int nl_family_handler(struct nl_msg *msg, void *arg)
nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);
- if (!tb[CTRL_ATTR_MCAST_GROUPS]) {
- fprintf(stderr, "Multicast group not found\n");
- return -1;
- }
+ if (!tb[CTRL_ATTR_MCAST_GROUPS])
+ return THERMAL_ERROR;
nla_for_each_nested(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], rem_mcgrp) {
@@ -111,11 +107,11 @@ static int nl_family_handler(struct nl_msg *msg, void *arg)
break;
}
- return 0;
+ return THERMAL_SUCCESS;
}
-int nl_get_multicast_id(struct nl_sock *sock, struct nl_cb *cb,
- const char *family, const char *group)
+static int nl_get_multicast_id(struct nl_sock *sock, struct nl_cb *cb,
+ const char *family, const char *group)
{
struct nl_msg *msg;
int ret = 0, ctrlid;
@@ -126,7 +122,7 @@ int nl_get_multicast_id(struct nl_sock *sock, struct nl_cb *cb,
msg = nlmsg_alloc();
if (!msg)
- return -ENOMEM;
+ return THERMAL_ERROR;
ctrlid = genl_ctrl_resolve(sock, "nlctrl");
@@ -152,7 +148,7 @@ int nl_thermal_connect(struct nl_sock **nl_sock, struct nl_cb **nl_cb)
cb = nl_cb_alloc(NL_CB_DEFAULT);
if (!cb)
- return -1;
+ return THERMAL_ERROR;
sock = nl_socket_alloc();
if (!sock)
@@ -161,22 +157,22 @@ int nl_thermal_connect(struct nl_sock **nl_sock, struct nl_cb **nl_cb)
if (genl_connect(sock))
goto out_socket_free;
- if (nl_cb_err(cb, NL_CB_CUSTOM, nl_error_handler, &err) ||
- nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, nl_finish_handler, &done) ||
- nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, nl_ack_handler, &done) ||
- nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, nl_seq_check_handler, &done))
- return -1;
+ if (nl_cb_err(cb, NL_CB_CUSTOM, nl_error_handler, &err) ||
+ nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, nl_finish_handler, &done) ||
+ nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, nl_ack_handler, &done) ||
+ nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, nl_seq_check_handler, &done))
+ return THERMAL_ERROR;
*nl_sock = sock;
*nl_cb = cb;
- return 0;
+ return THERMAL_SUCCESS;
out_socket_free:
nl_socket_free(sock);
out_cb_free:
nl_cb_put(cb);
- return -1;
+ return THERMAL_ERROR;
}
void nl_thermal_disconnect(struct nl_sock *nl_sock, struct nl_cb *nl_cb)
@@ -186,6 +182,22 @@ void nl_thermal_disconnect(struct nl_sock *nl_sock, struct nl_cb *nl_cb)
nl_cb_put(nl_cb);
}
+int nl_unsubscribe_thermal(struct nl_sock *nl_sock, struct nl_cb *nl_cb,
+ const char *group)
+{
+ int mcid;
+
+ mcid = nl_get_multicast_id(nl_sock, nl_cb, THERMAL_GENL_FAMILY_NAME,
+ group);
+ if (mcid < 0)
+ return THERMAL_ERROR;
+
+ if (nl_socket_drop_membership(nl_sock, mcid))
+ return THERMAL_ERROR;
+
+ return THERMAL_SUCCESS;
+}
+
int nl_subscribe_thermal(struct nl_sock *nl_sock, struct nl_cb *nl_cb,
const char *group)
{
@@ -193,13 +205,11 @@ int nl_subscribe_thermal(struct nl_sock *nl_sock, struct nl_cb *nl_cb,
mcid = nl_get_multicast_id(nl_sock, nl_cb, THERMAL_GENL_FAMILY_NAME,
group);
- if (mcid < 0) {
- fprintf(stderr, "Subscribing to multicast failed\n");
- return -1;
- }
+ if (mcid < 0)
+ return THERMAL_ERROR;
if (nl_socket_add_membership(nl_sock, mcid))
- return -1;
+ return THERMAL_ERROR;
- return 0;
+ return THERMAL_SUCCESS;
}
diff --git a/src/thermal.h b/src/thermal_nl.h
index 85814a1..ddf6356 100644
--- a/src/thermal.h
+++ b/src/thermal_nl.h
@@ -1,4 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
+/* Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org> */
#ifndef __THERMAL_H
#define __THERMAL_H
@@ -7,8 +8,6 @@
#include <netlink/genl/mngt.h>
#include <netlink/genl/ctrl.h>
-#include "libthermal.h"
-
struct thermal_handler {
int done;
int error;
@@ -33,6 +32,9 @@ struct thermal_handler_param {
extern int nl_subscribe_thermal(struct nl_sock *nl_sock, struct nl_cb *nl_cb,
const char *group);
+extern int nl_unsubscribe_thermal(struct nl_sock *nl_sock, struct nl_cb *nl_cb,
+ const char *group);
+
extern int nl_thermal_connect(struct nl_sock **nl_sock, struct nl_cb **nl_cb);
extern void nl_thermal_disconnect(struct nl_sock *nl_sock, struct nl_cb *nl_cb);
diff --git a/sync.sh b/sync.sh
new file mode 100755
index 0000000..2f1ea2f
--- /dev/null
+++ b/sync.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# set -ax
+GIT_LINUX_PATH=".linux"
+GIT_REPO=https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
+
+if [ ! -d $GIT_LINUX_PATH ]; then
+ echo " * Cloning $GIT_REPO"
+ git clone --depth 1 --sparse $GIT_REPO $GIT_LINUX_PATH
+fi
+
+pushd $GIT_LINUX_PATH > /dev/null
+
+# Update the official Linus' tree
+echo " * Updating $GIT_REPO"
+git pull
+
+GIT_LIB_THERMAL="tools/lib/thermal"
+GIT_THERMAL_LIB="tools/thermal/lib"
+GIT_SPARSE_SET="$GIT_LIB_THERMAL $GIT_THERMAL_LIB"
+
+echo " * Sparse checkout $GIT_SPARSE_SET"
+git sparse-checkout set $GIT_SPARSE_SET
+
+popd > /dev/null
+
+INCLUDE_PATH=src/include
+LIB_PATH=src/lib
+THERMAL_MANAGER_PATH=src/thermal-manager
+
+declare -A TARGETS
+
+TARGETS["include"]="$GIT_LINUX_PATH/$GIT_LIB_THERMAL/include/*.[ch]"
+TARGETS["src"]="$GIT_LINUX_PATH/$GIT_LIB_THERMAL/*.[ch] $GIT_LINUX_PATH/$GIT_LIB_THERMAL/Makefile"
+
+echo " * Updating source files"
+for TARGET in ${!TARGETS[@]}; do
+ for SRC in $(ls ${TARGETS[${TARGET}]}); do
+ diff -q $SRC $TARGET 2> /dev/null
+ if [ "$?" != "0" ]; then
+ echo " - Copying $SRC --> $TARGET"
+ cp $SRC $TARGET
+ fi
+ done
+done
+
+echo " * Patching source files"
+for PATCH in $(cat patches/patches.list); do
+ patch -p1 < patches/$PATCH
+done
+
+echo "Done"
diff --git a/tst/tst_thermal.c b/tst/tst_thermal.c
index 20e894d..ff89c13 100644
--- a/tst/tst_thermal.c
+++ b/tst/tst_thermal.c
@@ -11,7 +11,7 @@
#include <sys/stat.h>
#include <sys/types.h>
-#include "libthermal.h"
+#include "thermal.h"
#define MAX_EVENTS 10