1 // SPDX-License-Identifier: LGPL-2.1+ 2 // Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org> 3 #include <stdio.h> 4 #include <limits.h> 5 #include <thermal.h> 6 7 #include "thermal_nl.h" 8 9 int for_each_thermal_threshold(struct thermal_threshold *th, cb_th_t cb, void *arg) 10 { 11 int i, ret = 0; 12 13 if (!th) 14 return 0; 15 16 for (i = 0; th[i].temperature != INT_MAX; i++) 17 ret |= cb(&th[i], arg); 18 19 return ret; 20 } 21 22 int for_each_thermal_cdev(struct thermal_cdev *cdev, cb_tc_t cb, void *arg) 23 { 24 int i, ret = 0; 25 26 if (!cdev) 27 return 0; 28 29 for (i = 0; cdev[i].id != -1; i++) 30 ret |= cb(&cdev[i], arg); 31 32 return ret; 33 } 34 35 int for_each_thermal_trip(struct thermal_trip *tt, cb_tt_t cb, void *arg) 36 { 37 int i, ret = 0; 38 39 if (!tt) 40 return 0; 41 42 for (i = 0; tt[i].id != -1; i++) 43 ret |= cb(&tt[i], arg); 44 45 return ret; 46 } 47 48 int for_each_thermal_zone(struct thermal_zone *tz, cb_tz_t cb, void *arg) 49 { 50 int i, ret = 0; 51 52 if (!tz) 53 return 0; 54 55 for (i = 0; tz[i].id != -1; i++) 56 ret |= cb(&tz[i], arg); 57 58 return ret; 59 } 60 61 struct thermal_zone *thermal_zone_find_by_name(struct thermal_zone *tz, 62 const char *name) 63 { 64 int i; 65 66 if (!tz || !name) 67 return NULL; 68 69 for (i = 0; tz[i].id != -1; i++) { 70 if (!strcmp(tz[i].name, name)) 71 return &tz[i]; 72 } 73 74 return NULL; 75 } 76 77 struct thermal_zone *thermal_zone_find_by_id(struct thermal_zone *tz, int id) 78 { 79 int i; 80 81 if (!tz || id < 0) 82 return NULL; 83 84 for (i = 0; tz[i].id != -1; i++) { 85 if (tz[i].id == id) 86 return &tz[i]; 87 } 88 89 return NULL; 90 } 91 92 static int __thermal_zone_discover(struct thermal_zone *tz, void *th) 93 { 94 if (thermal_cmd_get_trip(th, tz) < 0) 95 return -1; 96 97 if (thermal_cmd_threshold_get(th, tz)) 98 return -1; 99 100 if (thermal_cmd_get_governor(th, tz)) 101 return -1; 102 103 return 0; 104 } 105 106 struct thermal_zone *thermal_zone_discover(struct thermal_handler *th) 107 { 108 struct thermal_zone *tz; 109 110 if (thermal_cmd_get_tz(th, &tz) < 0) 111 return NULL; 112 113 if (for_each_thermal_zone(tz, __thermal_zone_discover, th)) 114 return NULL; 115 116 return tz; 117 } 118 119 void thermal_exit(struct thermal_handler *th) 120 { 121 thermal_cmd_exit(th); 122 thermal_events_exit(th); 123 thermal_sampling_exit(th); 124 125 free(th); 126 } 127 128 struct thermal_handler *thermal_init(struct thermal_ops *ops) 129 { 130 struct thermal_handler *th; 131 132 th = malloc(sizeof(*th)); 133 if (!th) 134 return NULL; 135 th->ops = ops; 136 137 if (thermal_events_init(th)) 138 goto out_free; 139 140 if (thermal_sampling_init(th)) 141 goto out_free; 142 143 if (thermal_cmd_init(th)) 144 goto out_free; 145 146 return th; 147 148 out_free: 149 free(th); 150 151 return NULL; 152 } 153