1 | // SPDX-License-Identifier: LGPL-2.1+ |
2 | // Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org> |
3 | #include <errno.h> |
4 | #include <stdio.h> |
5 | #include <stdlib.h> |
6 | #include <unistd.h> |
7 | |
8 | #include <thermal.h> |
9 | #include "thermal_nl.h" |
10 | |
11 | static int handle_thermal_sample(struct nl_msg *n, void *arg) |
12 | { |
13 | struct nlmsghdr *nlh = nlmsg_hdr(n); |
14 | struct genlmsghdr *genlhdr = genlmsg_hdr(nlh); |
15 | struct nlattr *attrs[THERMAL_GENL_ATTR_MAX + 1]; |
16 | struct thermal_handler_param *thp = arg; |
17 | struct thermal_handler *th = thp->th; |
18 | |
19 | genlmsg_parse(nlh, 0, attrs, THERMAL_GENL_ATTR_MAX, NULL); |
20 | |
21 | switch (genlhdr->cmd) { |
22 | |
23 | case THERMAL_GENL_SAMPLING_TEMP: |
24 | return th->ops->sampling.tz_temp( |
25 | nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]), |
26 | nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TEMP]), arg); |
27 | default: |
28 | return THERMAL_ERROR; |
29 | } |
30 | } |
31 | |
32 | thermal_error_t thermal_sampling_handle(struct thermal_handler *th, void *arg) |
33 | { |
34 | struct thermal_handler_param thp = { .th = th, .arg = arg }; |
35 | |
36 | if (!th) |
37 | return THERMAL_ERROR; |
38 | |
39 | if (nl_cb_set(th->cb_sampling, NL_CB_VALID, NL_CB_CUSTOM, |
40 | handle_thermal_sample, &thp)) |
41 | return THERMAL_ERROR; |
42 | |
43 | return nl_recvmsgs(th->sk_sampling, th->cb_sampling); |
44 | } |
45 | |
46 | int thermal_sampling_fd(struct thermal_handler *th) |
47 | { |
48 | if (!th) |
49 | return -1; |
50 | |
51 | return nl_socket_get_fd(th->sk_sampling); |
52 | } |
53 | |
54 | thermal_error_t thermal_sampling_exit(struct thermal_handler *th) |
55 | { |
56 | if (nl_unsubscribe_thermal(nl_sock: th->sk_sampling, nl_cb: th->cb_sampling, |
57 | group: THERMAL_GENL_SAMPLING_GROUP_NAME)) |
58 | return THERMAL_ERROR; |
59 | |
60 | nl_thermal_disconnect(nl_sock: th->sk_sampling, nl_cb: th->cb_sampling); |
61 | |
62 | return THERMAL_SUCCESS; |
63 | } |
64 | |
65 | thermal_error_t thermal_sampling_init(struct thermal_handler *th) |
66 | { |
67 | if (nl_thermal_connect(nl_sock: &th->sk_sampling, nl_cb: &th->cb_sampling)) |
68 | return THERMAL_ERROR; |
69 | |
70 | if (nl_subscribe_thermal(nl_sock: th->sk_sampling, nl_cb: th->cb_sampling, |
71 | group: THERMAL_GENL_SAMPLING_GROUP_NAME)) |
72 | return THERMAL_ERROR; |
73 | |
74 | return THERMAL_SUCCESS; |
75 | } |
76 | |