~ubuntu-branches/ubuntu/utopic/thermald/utopic

« back to all changes in this revision

Viewing changes to .pc/0005-Adjust-for-coretemp-path-change.patch/src/thd_engine_default.cpp

  • Committer: Package Import Robot
  • Author(s): Colin King
  • Date: 2014-05-19 12:41:22 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20140519124122-zan11arvjxtbqcq5
Tags: 1.2-1
* Adjust for coretemp path change
* Deny non root users to send system bus dbus messages
* Remove compile warning
* Remove rpmlint warning for manual page
* Remove old patches that are now included into version 1.2
* Sync up with version 1.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * cthd_engine_defualt.cpp: Default thermal engine
 
3
 *
 
4
 * Copyright (C) 2013 Intel Corporation. All rights reserved.
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU General Public License version
 
8
 * 2 or later as published by the Free Software Foundation.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
18
 * 02110-1301, USA.
 
19
 *
 
20
 *
 
21
 * Author Name <Srinivas.Pandruvada@linux.intel.com>
 
22
 *
 
23
 */
 
24
 
 
25
#include <dirent.h>
 
26
#include <errno.h>
 
27
#include <sys/types.h>
 
28
#include "thd_engine_default.h"
 
29
#include "thd_zone_cpu.h"
 
30
#include "thd_zone_generic.h"
 
31
#include "thd_cdev_gen_sysfs.h"
 
32
#include "thd_cdev_cpufreq.h"
 
33
#include "thd_cdev_rapl.h"
 
34
#include "thd_cdev_intel_pstate_driver.h"
 
35
#include "thd_zone_surface.h"
 
36
#include "thd_cdev_msr_rapl.h"
 
37
 
 
38
#define ACTIVATE_SURFACE
 
39
 
 
40
// Default CPU cooling devices, which are not part of thermal sysfs
 
41
// Since non trivial initialization is not supported, we init all fields even if they are not needed
 
42
/* Some security scan handler can't parse, the following block and generate unnecessary errors.
 
43
 * hiding good ones. So init in old style compatible to C++
 
44
 
 
45
 static cooling_dev_t cpu_def_cooling_devices[] = {
 
46
 {      .status = true,
 
47
 .mask = CDEV_DEF_BIT_UNIT_VAL | CDEV_DEF_BIT_READ_BACK | CDEV_DEF_BIT_MIN_STATE | CDEV_DEF_BIT_STEP,
 
48
 .index = 0, .unit_val = ABSOULUTE_VALUE, .min_state = 0, .max_state = 0, .inc_dec_step = 5,
 
49
 .read_back = false, .auto_down_control = false,
 
50
 .type_string = "intel_powerclamp", .path_str = "",
 
51
 .debounce_interval = 4, .pid_enable = false,
 
52
 .pid = {0.0, 0.0, 0.0}},
 
53
 };
 
54
 */
 
55
static cooling_dev_t cpu_def_cooling_devices[] = { { true, CDEV_DEF_BIT_UNIT_VAL
 
56
                | CDEV_DEF_BIT_READ_BACK | CDEV_DEF_BIT_MIN_STATE | CDEV_DEF_BIT_STEP,
 
57
                0, ABSOULUTE_VALUE, 0, 0, 5, false, false, "intel_powerclamp", "", 4,
 
58
                false, { 0.0, 0.0, 0.0 } } };
 
59
 
 
60
cthd_engine_default::~cthd_engine_default() {
 
61
        if (parser_init_done)
 
62
                parser.parser_deinit();
 
63
}
 
64
 
 
65
int cthd_engine_default::parser_init() {
 
66
        if (parser_init_done)
 
67
                return THD_SUCCESS;
 
68
        if (parser.parser_init() == THD_SUCCESS) {
 
69
                if (parser.start_parse() == THD_SUCCESS) {
 
70
                        parser.dump_thermal_conf();
 
71
                        parser_init_done = true;
 
72
                        return THD_SUCCESS;
 
73
                }
 
74
        }
 
75
 
 
76
        return THD_ERROR;
 
77
}
 
78
 
 
79
void cthd_engine_default::parser_deinit() {
 
80
        if (parser_init_done) {
 
81
                parser.parser_deinit();
 
82
                parser_init_done = false;
 
83
        }
 
84
}
 
85
 
 
86
int cthd_engine_default::read_thermal_sensors() {
 
87
        int index;
 
88
        DIR *dir;
 
89
        struct dirent *entry;
 
90
        int sensor_mask = 0x0f;
 
91
        cthd_sensor *sensor;
 
92
        const std::string base_path = "/sys/devices/platform/";
 
93
 
 
94
        thd_read_default_thermal_sensors();
 
95
        index = sensor_count;
 
96
 
 
97
        sensor = search_sensor("pkg-temp-0");
 
98
        if (sensor) {
 
99
                // Force this to support async
 
100
                sensor->set_async_capable(true);
 
101
        }
 
102
        // Default CPU temperature zone
 
103
        // Find path to read DTS temperature
 
104
        if ((dir = opendir(base_path.c_str())) != NULL) {
 
105
                while ((entry = readdir(dir)) != NULL) {
 
106
                        if (!strncmp(entry->d_name, "coretemp.", strlen("coretemp."))) {
 
107
                                int cnt = 0;
 
108
                                unsigned int mask = 0x1;
 
109
                                do {
 
110
                                        if (sensor_mask & mask) {
 
111
                                                std::stringstream temp_input_str;
 
112
                                                std::string path = base_path + entry->d_name + "/";
 
113
                                                csys_fs dts_sysfs(path.c_str());
 
114
                                                temp_input_str << "temp" << cnt << "_input";
 
115
                                                if (dts_sysfs.exists(temp_input_str.str())) {
 
116
                                                        cthd_sensor *sensor = new cthd_sensor(index,
 
117
                                                                        base_path + entry->d_name + "/"
 
118
                                                                                        + temp_input_str.str(),
 
119
                                                                        temp_input_str.str(), SENSOR_TYPE_RAW);
 
120
                                                        if (sensor->sensor_update() != THD_SUCCESS) {
 
121
                                                                delete sensor;
 
122
                                                                closedir(dir);
 
123
                                                                return THD_ERROR;
 
124
                                                        }
 
125
                                                        sensors.push_back(sensor);
 
126
                                                        ++index;
 
127
                                                }
 
128
                                        }
 
129
                                        mask = (mask << 1);
 
130
                                        cnt++;
 
131
                                } while (mask != 0);
 
132
 
 
133
                        }
 
134
                }
 
135
                closedir(dir);
 
136
        }
 
137
        if (index == sensor_count) {
 
138
                // No coretemp sysfs exist, try hwmon
 
139
                thd_log_warn("Thermal DTS: No coretemp sysfs, trying hwmon \n");
 
140
                cthd_sensor *sensor = new cthd_sensor(index,
 
141
                                "/sys/class/hwmon/hwmon0/temp1_input", "hwmon",
 
142
                                SENSOR_TYPE_RAW);
 
143
                if (sensor->sensor_update() != THD_SUCCESS) {
 
144
                        delete sensor;
 
145
                        return THD_ERROR;
 
146
                }
 
147
                sensors.push_back(sensor);
 
148
                ++index;
 
149
 
 
150
                if (index == sensor_count) {
 
151
                        thd_log_error("Thermal DTS or hwmon: No Zones present: \n");
 
152
                        return THD_FATAL_ERROR;
 
153
                }
 
154
        }
 
155
 
 
156
        // Add from XML sensor config
 
157
        if (!parser_init() && parser.platform_matched()) {
 
158
                for (int i = 0; i < parser.sensor_count(); ++i) {
 
159
                        thermal_sensor_t *sensor_config = parser.get_sensor_dev_index(i);
 
160
                        if (!sensor_config)
 
161
                                continue;
 
162
                        cthd_sensor *sensor = search_sensor(sensor_config->name);
 
163
                        if (sensor) {
 
164
                                if (sensor_config->mask & SENSOR_DEF_BIT_PATH)
 
165
                                        sensor->update_path(sensor_config->path);
 
166
                                if (sensor_config->mask & SENSOR_DEF_BIT_ASYNC_CAPABLE)
 
167
                                        sensor->set_async_capable(sensor_config->async_capable);
 
168
                        } else {
 
169
                                cthd_sensor *sensor_new = new cthd_sensor(index,
 
170
                                                sensor_config->path, sensor_config->name,
 
171
                                                SENSOR_TYPE_RAW);
 
172
                                if (sensor_new->sensor_update() != THD_SUCCESS) {
 
173
                                        delete sensor_new;
 
174
                                        continue;
 
175
                                }
 
176
                                sensors.push_back(sensor_new);
 
177
                                ++index;
 
178
                        }
 
179
                }
 
180
                sensor_count = index;
 
181
        }
 
182
 
 
183
        for (unsigned int i = 0; i < sensors.size(); ++i) {
 
184
                sensors[i]->sensor_dump();
 
185
        }
 
186
 
 
187
        return THD_SUCCESS;
 
188
}
 
189
 
 
190
int cthd_engine_default::read_thermal_zones() {
 
191
        int count = 0;
 
192
        DIR *dir;
 
193
        struct dirent *entry;
 
194
        const std::string base_path = "/sys/devices/platform/";
 
195
 
 
196
        thd_read_default_thermal_zones();
 
197
        count = zone_count;
 
198
 
 
199
        if (!search_zone("cpu")) {
 
200
                bool cpu_zone_created = false;
 
201
                thd_log_info("zone cpu will be created \n");
 
202
                // Default CPU temperature zone
 
203
                // Find path to read DTS temperature
 
204
                if ((dir = opendir(base_path.c_str())) != NULL) {
 
205
                        while ((entry = readdir(dir)) != NULL) {
 
206
                                if (!strncmp(entry->d_name, "coretemp.", strlen("coretemp."))) {
 
207
                                        cthd_zone_cpu *zone = new cthd_zone_cpu(count,
 
208
                                                        base_path + entry->d_name + "/",
 
209
                                                        atoi(entry->d_name + strlen("coretemp.")));
 
210
                                        if (zone->zone_update() == THD_SUCCESS) {
 
211
                                                zone->set_zone_active();
 
212
                                                zones.push_back(zone);
 
213
                                                ++count;
 
214
                                                cpu_zone_created = true;
 
215
                                        } else {
 
216
                                                delete zone;
 
217
                                        }
 
218
                                }
 
219
                        }
 
220
                        closedir(dir);
 
221
                }
 
222
#ifdef ACTIVATE_SURFACE
 
223
//      Enable when skin sensors are standardized
 
224
        cthd_zone *surface;
 
225
        surface = search_zone("Surface");
 
226
 
 
227
        if (!surface || (surface && !surface->zone_active_status())) {
 
228
                cthd_zone_surface *zone = new cthd_zone_surface(count);
 
229
                if (zone->zone_update() == THD_SUCCESS) {
 
230
                        zones.push_back(zone);
 
231
                        ++count;
 
232
                        zone->set_zone_active();
 
233
                } else
 
234
                        delete zone;
 
235
        } else {
 
236
                thd_log_info("TSKN sensor was activated by config \n");
 
237
        }
 
238
#endif
 
239
 
 
240
                if (!cpu_zone_created) {
 
241
                        // No coretemp sysfs exist, try hwmon
 
242
                        thd_log_warn("Thermal DTS: No coretemp sysfs, trying hwmon \n");
 
243
 
 
244
                        cthd_zone_cpu *zone = new cthd_zone_cpu(count,
 
245
                                        "/sys/class/hwmon/hwmon0/", 0);
 
246
                        if (zone->zone_update() == THD_SUCCESS) {
 
247
                                zone->set_zone_active();
 
248
                                zones.push_back(zone);
 
249
                                ++count;
 
250
                                cpu_zone_created = true;
 
251
                        } else {
 
252
                                delete zone;
 
253
                        }
 
254
 
 
255
                        if (!cpu_zone_created) {
 
256
                                thd_log_error("Thermal DTS or hwmon: No Zones present: \n");
 
257
                                return THD_FATAL_ERROR;
 
258
                        }
 
259
                }
 
260
        }
 
261
        zone_count = count;
 
262
 
 
263
        // Add from XML thermal zone
 
264
        if (!parser_init() && parser.platform_matched()) {
 
265
                for (int i = 0; i < parser.zone_count(); ++i) {
 
266
                        thermal_zone_t *zone_config = parser.get_zone_dev_index(i);
 
267
                        if (!zone_config)
 
268
                                continue;
 
269
                        cthd_zone *zone = search_zone(zone_config->type);
 
270
                        if (zone) {
 
271
                                thd_log_info("Zone already present %s \n", zone_config->type.c_str());
 
272
                                for (unsigned int k = 0; k < zone_config->trip_pts.size();
 
273
                                                ++k) {
 
274
                                        trip_point_t &trip_pt_config = zone_config->trip_pts[k];
 
275
                                        cthd_sensor *sensor = search_sensor(
 
276
                                                        trip_pt_config.sensor_type);
 
277
                                        if (!sensor) {
 
278
                                                thd_log_error("XML zone: invalid sensor type \n");
 
279
                                                // This will update the trip tempearture for the matching
 
280
                                                // trip type
 
281
                                                if (trip_pt_config.temperature) {
 
282
                                                        cthd_trip_point trip_pt(zone->get_trip_count(),
 
283
                                                                        trip_pt_config.trip_pt_type,
 
284
                                                                        trip_pt_config.temperature,
 
285
                                                                        trip_pt_config.hyst, zone->get_zone_index(),
 
286
                                                                        -1, trip_pt_config.control_type);
 
287
                                                        zone->update_trip_temp(trip_pt);
 
288
                                                }
 
289
                                                continue;
 
290
                                        }
 
291
                                        zone->bind_sensor(sensor);
 
292
                                        cthd_trip_point trip_pt(zone->get_trip_count(),
 
293
                                                        trip_pt_config.trip_pt_type,
 
294
                                                        trip_pt_config.temperature, trip_pt_config.hyst,
 
295
                                                        zone->get_zone_index(), sensor->get_index(),
 
296
                                                        trip_pt_config.control_type);
 
297
                                        // bind cdev
 
298
                                        for (unsigned int j = 0;
 
299
                                                        j < trip_pt_config.cdev_trips.size(); ++j) {
 
300
                                                cthd_cdev *cdev = search_cdev(
 
301
                                                                trip_pt_config.cdev_trips[j].type);
 
302
                                                if (cdev) {
 
303
                                                        trip_pt.thd_trip_point_add_cdev(*cdev,
 
304
                                                                        trip_pt_config.cdev_trips[j].influence);
 
305
                                                }
 
306
                                        }
 
307
                                        zone->add_trip(trip_pt);
 
308
                                }
 
309
                                zone->set_zone_active();
 
310
                        } else {
 
311
                                cthd_zone_generic *zone = new cthd_zone_generic(count, i,
 
312
                                                zone_config->type);
 
313
                                if (zone->zone_update() == THD_SUCCESS) {
 
314
                                        zones.push_back(zone);
 
315
                                        ++count;
 
316
                                        zone->set_zone_active();
 
317
                                } else
 
318
                                        delete zone;
 
319
                        }
 
320
                }
 
321
        }
 
322
        zone_count = count;
 
323
 
 
324
        for (unsigned int i = 0; i < zones.size(); ++i) {
 
325
                zones[i]->zone_dump();
 
326
        }
 
327
        return THD_SUCCESS;
 
328
}
 
329
 
 
330
int cthd_engine_default::add_replace_cdev(cooling_dev_t *config) {
 
331
        cthd_cdev *cdev;
 
332
        bool cdev_present = false;
 
333
        int current_cdev_index = cdev_cnt;
 
334
        bool percent_unit = false;
 
335
 
 
336
        // Check if there is existing cdev with this name and path
 
337
        cdev = search_cdev(config->type_string);
 
338
        if (cdev) {
 
339
                cdev_present = true;
 
340
                // Also check for path, some device like FAN has multiple paths for same type_str
 
341
                std::string base_path = cdev->get_base_path();
 
342
                if (config->path_str.size() && config->path_str != base_path) {
 
343
                        cdev_present = false;
 
344
                }
 
345
        }
 
346
        if (!cdev_present) {
 
347
                // create new
 
348
                cdev = new cthd_gen_sysfs_cdev(current_cdev_index, config->path_str);
 
349
                if (!cdev)
 
350
                        return THD_ERROR;
 
351
                cdev->set_cdev_type(config->type_string);
 
352
                if (cdev->update() != THD_SUCCESS) {
 
353
                        delete cdev;
 
354
                        return THD_ERROR;
 
355
                }
 
356
                cdevs.push_back(cdev);
 
357
        }
 
358
 
 
359
        if (config->mask & CDEV_DEF_BIT_UNIT_VAL) {
 
360
                if (config->unit_val == RELATIVE_PERCENTAGES)
 
361
                        percent_unit = true;
 
362
        }
 
363
        if (config->mask & CDEV_DEF_BIT_AUTO_DOWN)
 
364
                cdev->set_down_adjust_control(config->auto_down_control);
 
365
        if (config->mask & CDEV_DEF_BIT_STEP) {
 
366
                if (percent_unit)
 
367
                        cdev->set_inc_dec_value(
 
368
                                        cdev->get_curr_state() * config->inc_dec_step / 100);
 
369
                else
 
370
                        cdev->set_inc_dec_value(config->inc_dec_step);
 
371
        }
 
372
        if (config->mask & CDEV_DEF_BIT_MIN_STATE) {
 
373
                if (percent_unit)
 
374
                        cdev->thd_cdev_set_min_state_param(
 
375
                                        cdev->get_curr_state() * config->min_state / 100);
 
376
                else
 
377
                        cdev->thd_cdev_set_min_state_param(config->min_state);
 
378
        }
 
379
        if (config->mask & CDEV_DEF_BIT_MAX_STATE) {
 
380
                if (percent_unit)
 
381
                        cdev->thd_cdev_set_max_state_param(
 
382
                                        cdev->get_curr_state() * config->max_state / 100);
 
383
                else
 
384
                        cdev->thd_cdev_set_max_state_param(config->max_state);
 
385
        }
 
386
        if (config->mask & CDEV_DEF_BIT_READ_BACK)
 
387
                cdev->thd_cdev_set_read_back_param(config->read_back);
 
388
 
 
389
        if (config->mask & CDEV_DEF_BIT_DEBOUNCE_VAL)
 
390
                cdev->set_debounce_interval(config->debounce_interval);
 
391
 
 
392
        if (config->mask & CDEV_DEF_BIT_PID_PARAMS) {
 
393
                cdev->enable_pid();
 
394
                cdev->set_pid_param(config->pid.Kp, config->pid.Ki, config->pid.Kd);
 
395
        }
 
396
        //cdev->cdev_dump();
 
397
 
 
398
        current_cdev_index++;
 
399
 
 
400
        return THD_SUCCESS;
 
401
 
 
402
}
 
403
 
 
404
int cthd_engine_default::read_cooling_devices() {
 
405
        int size;
 
406
        int i;
 
407
 
 
408
        // Read first all the default cooling devices added by kernel
 
409
        thd_read_default_cooling_devices();
 
410
        int current_cdev_index = cdev_cnt;
 
411
 
 
412
        // Add RAPL cooling device
 
413
        cthd_sysfs_cdev_rapl *rapl_dev = new cthd_sysfs_cdev_rapl(cdev_cnt, 0);
 
414
        rapl_dev->set_cdev_type("rapl_controller");
 
415
        if (rapl_dev->update() == THD_SUCCESS) {
 
416
                cdevs.push_back(rapl_dev);
 
417
                ++cdev_cnt;
 
418
        } else {
 
419
                delete rapl_dev;
 
420
                if (processor_id_match()) {
 
421
                        // RAPL control via MSR
 
422
                        cthd_cdev_rapl_msr *rapl_msr_dev = new cthd_cdev_rapl_msr(cdev_cnt,
 
423
                                        0);
 
424
                        rapl_msr_dev->set_cdev_type("rapl_controller");
 
425
                        if (rapl_msr_dev->update() == THD_SUCCESS) {
 
426
                                cdevs.push_back(rapl_msr_dev);
 
427
                                ++cdev_cnt;
 
428
                        } else
 
429
                                delete rapl_msr_dev;
 
430
                }
 
431
        }
 
432
        // Add Intel P state driver as cdev
 
433
        cthd_intel_p_state_cdev *pstate_dev = new cthd_intel_p_state_cdev(cdev_cnt);
 
434
        pstate_dev->set_cdev_type("intel_pstate");
 
435
        if (pstate_dev->update() == THD_SUCCESS) {
 
436
                cdevs.push_back(pstate_dev);
 
437
                ++cdev_cnt;
 
438
        } else
 
439
                delete pstate_dev;
 
440
 
 
441
        // Add statically defined cooling devices
 
442
        size = sizeof(cpu_def_cooling_devices) / sizeof(cooling_dev_t);
 
443
        for (i = 0; i < size; ++i) {
 
444
                if (add_replace_cdev(&cpu_def_cooling_devices[i]) == THD_SUCCESS)
 
445
                        current_cdev_index++;
 
446
                cdev_cnt = current_cdev_index;
 
447
        }
 
448
 
 
449
        // Add from XML cooling device config
 
450
        if (!parser_init() && parser.platform_matched()) {
 
451
                for (int i = 0; i < parser.cdev_count(); ++i) {
 
452
                        cooling_dev_t *cdev_config = parser.get_cool_dev_index(i);
 
453
                        if (!cdev_config)
 
454
                                continue;
 
455
 
 
456
                        if (add_replace_cdev(cdev_config) == THD_SUCCESS) {
 
457
                                current_cdev_index++;
 
458
                        }
 
459
                }
 
460
                cdev_cnt = current_cdev_index;
 
461
        }
 
462
 
 
463
        cthd_cdev_cpufreq *cpu_freq_dev = new cthd_cdev_cpufreq(cdev_cnt, -1);
 
464
        cpu_freq_dev->set_cdev_type("cpufreq");
 
465
        if (cpu_freq_dev->update() == THD_SUCCESS) {
 
466
                cdevs.push_back(cpu_freq_dev);
 
467
                ++cdev_cnt;
 
468
        } else
 
469
                delete cpu_freq_dev;
 
470
 
 
471
        // Dump all cooling devices
 
472
        for (unsigned i = 0; i < cdevs.size(); ++i) {
 
473
                cdevs[i]->cdev_dump();
 
474
        }
 
475
 
 
476
        return THD_SUCCESS;
 
477
}
 
478