pass: parser: Add support of thermal monitor for each h/w resource 69/174369/7
authorChanwoo Choi <cw00.choi@samsung.com>
Thu, 22 Mar 2018 10:56:26 +0000 (19:56 +0900)
committerChanwoo Choi <cw00.choi@samsung.com>
Fri, 6 Apr 2018 05:54:28 +0000 (14:54 +0900)
In order to use/support Thermal Monitor, each h/w resource (e.g., CPU/GPU)
have to write the configuration such as thermal scenario name, temperature
and timer interval for each thermal scenario. Parse the property for
Thermal Monitor.

Change-Id: I3aa08bcfbbb037897fff42cfe24aabc732610e05
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
src/pass/pass-parser.c
src/pass/pass.h

index c14f27f..cedbf76 100644 (file)
@@ -91,10 +91,18 @@ static int parse_scenario(struct parse_result *result,
                scenario->state = is_supported(result->value);
                if (scenario->state < 0)
                        return -EINVAL;
+
+       /* Parse properties for only PASS_MODULE_PMQOS */
        } else if (MATCH(result->name, "min_level")) {
                scenario->pmqos.min_level = atoi(result->value);
        } else if (MATCH(result->name, "max_level")) {
                scenario->pmqos.max_level = atoi(result->value);
+
+       /* Parse properties for only PASS_MODULE_THERMAL */
+       } else if (MATCH(result->name, "temperature")) {
+               scenario->thermal.temperature = atoi(result->value);
+       } else if (MATCH(result->name, "timer_interval_ms")) {
+               scenario->thermal.timer_interval = atoi(result->value);
        }
 
        return 0;
@@ -221,6 +229,47 @@ static int parse_pmqos(struct parse_result *result, void *user_data)
        return 0;
 }
 
+static int parse_thermal(struct parse_result *result, void *user_data)
+{
+       struct pass_resource *res = user_data;
+       struct pass_thermal *thermal = &res->thermal;
+
+       if (!result)
+               return 0;
+
+       if (!result->section || !result->name || !result->value)
+               return 0;
+
+       /* Parse 'thermal' section */
+       if (MATCH(result->name, "thermal_support")) {
+               thermal->state = is_supported(result->value);
+               if (thermal->state < 0)
+                       return -EINVAL;
+       } else if (MATCH(result->name, "thermal_number_of_scenario")) {
+               unsigned int num_scenarios;
+
+               num_scenarios = atoi(result->value);
+               if (num_scenarios > MAX_NUM) {
+                       _E("cannot parse %s\n", result->name);
+                       return -EINVAL;
+               }
+
+               if (num_scenarios > 0 && !thermal->scenarios) {
+                       thermal->scenarios = calloc(num_scenarios,
+                                       sizeof(struct pass_scenario));
+                       if (!thermal->scenarios) {
+                               _E("cannot allocate memory for Scenario\n");
+                               return -EINVAL;
+                       }
+                       thermal->num_scenarios = num_scenarios;
+               }
+       } else if (MATCH(result->name, "thermal_timer_interval_ms")) {
+               thermal->timer_interval  = atoi(result->value);
+       }
+
+       return 0;
+}
+
 static int parse_core(struct parse_result *result, void *user_data)
 {
        struct pass_resource *res = user_data;
@@ -279,6 +328,7 @@ static int parse_each_resource(struct parse_result *result, void *user_data)
 {
        struct pass_resource *res = user_data;
        struct pass_pmqos *pmqos = &res->pmqos;
+       struct pass_thermal *thermal = &res->thermal;
        char section_name[BUFF_MAX];
        int i, ret;
 
@@ -340,6 +390,32 @@ static int parse_each_resource(struct parse_result *result, void *user_data)
                }
        }
 
+       /* Parsing 'thermal' section */
+       if (MATCH(result->section, "thermal")) {
+               ret = parse_thermal(result, user_data);
+               if (ret < 0) {
+                       _E("cannot parse 'thermal' section\n");
+                       return ret;
+               }
+
+               goto out;
+       }
+
+       /* Parsing 'thermal.scenario' section */
+       for (i = 0; i < thermal->num_scenarios; i++) {
+               ret = snprintf(section_name, BUFF_MAX, "thermal.scenario%d", i);
+
+               if (MATCH(result->section, section_name)) {
+                       ret = parse_scenario(result, &thermal->scenarios[i]);
+                       if (ret < 0) {
+                               _E("cannot parse 'thermal.scenario%d' section\n", i);
+                               return ret;
+                       }
+
+                       goto out;
+               }
+       }
+
 out:
        return 0;
 }
@@ -544,6 +620,7 @@ int pass_get_each_resource_config(struct pass_resource *res, char *path)
 {
        struct pass_cpuhp *cpuhp;
        struct pass_pmqos *pmqos;
+       struct pass_thermal *thermal;
        int ret;
 
        if (!res)
@@ -551,6 +628,7 @@ int pass_get_each_resource_config(struct pass_resource *res, char *path)
 
        cpuhp = &res->cpuhp;
        pmqos = &res->pmqos;
+       thermal = &res->thermal;
 
        res->config_data.state = PASS_UNUSED;
        res->config_data.gov_type = 0;
@@ -573,6 +651,9 @@ int pass_get_each_resource_config(struct pass_resource *res, char *path)
        /* Initialize the PMQoS's data */
        pmqos->state = PASS_UNUSED;
 
+       /* Initialize the Thermal's data */
+       thermal->state = PASS_UNUSED;
+
        ret = config_parse(path, parse_each_resource, res);
        if (ret < 0) {
                _E("cannot parse %s\n", path);
@@ -612,5 +693,11 @@ void pass_put_each_resource_config(struct pass_resource *res)
                res->pmqos.scenarios = NULL;
        }
 
+       if (res->thermal.scenarios) {
+               free(res->thermal.scenarios);
+               res->thermal.scenarios = NULL;
+               res->thermal.num_scenarios = 0;
+       }
+
        res->pmqos.num_scenarios = 0;
 }
index 7d6db7c..55c147a 100644 (file)
@@ -168,6 +168,9 @@ struct pass_level {
  * - locked_time: the requiired locking time of scenario.
  * - min_level: the required minimum PASS's level.
  * - max_level: the required maximum PASS's level.
+ * @pmqos: the private data for PASS_MODULE_THERMAL
+ * - temperature: the temperature of the scenario.
+ * - timer_interval: the interval of timer-based monitor (unit: millisecond).
  */
 struct pass_scenario {
        char name[BUFF_MAX];
@@ -179,6 +182,11 @@ struct pass_scenario {
                unsigned int min_level;
                unsigned int max_level;
        } pmqos;
+
+       struct {
+               int temperature;
+               int timer_interval;
+       } thermal;
 };
 
 /******************************************************
@@ -284,6 +292,29 @@ struct pass_cpuhp {
        struct pass_hotplug *hotplug;
 };
 
+/*
+ * struct pass_thermal - Represent Thermal Monitor module
+ *
+ * @state: the state of Thermal Monitor (either enabled or disabled).
+ * @num_scenarios: the number of scenarios.
+ * @scenarios: the list of scenarios.
+ * @timer_interval: the interval of timer-based  monitor (unit: millisecond).
+ * @curr_scenario_idx: the index of current thermal scenario.
+ * @curr_temp: the current temperature.
+ *
+ * Thermal Monitor may be enabled or disabled according to configuration.
+ */
+struct pass_thermal {
+       enum pass_state state;
+
+       unsigned int num_scenarios;
+       struct pass_scenario *scenarios;
+
+       unsigned int timer_interval;
+       int curr_scenario_idx;
+       int curr_temp;
+};
+
 /******************************************************
  *                   PASS Resource                    *
  ******************************************************/
@@ -412,6 +443,7 @@ struct pass_resource_init_data {
  * @resmon: represents ResMon (Resource Monitor) module.
  * @cpuhp: represents CPUHP (CPU Hotplug Manager) module.
  * @pmqos: represents PMQoS module.
+ * @thermal: represents Thermal Monitor module.
  */
 struct pass_resource {
        enum pass_state state;
@@ -432,6 +464,7 @@ struct pass_resource {
 
        struct pass_cpuhp cpuhp;
        struct pass_pmqos pmqos;
+       struct pass_thermal thermal;
 };
 
 /******************************************************