thermal: Support dbus activation for thermal f/w 10/210610/6 accepted/tizen/unified/20190731.112548 submit/tizen/20190730.044254
authorDongwoo Lee <dwoo08.lee@samsung.com>
Tue, 23 Jul 2019 02:07:11 +0000 (11:07 +0900)
committerDongwoo Lee <dwoo08.lee@samsung.com>
Tue, 30 Jul 2019 01:35:13 +0000 (10:35 +0900)
Since resource monitoring first announce the temperature state a
single seconds later after all initialization over, to support dbus
activation for thermal f/w, temperature should be set during
initialization. To support this feature, current temprature is
retrived in advance while thermal is initialized, and it will be
announced before sd_notify called.

Change-Id: I83dae123a51fbdd953fe467ae408cae1a100c059
Signed-off-by: Dongwoo Lee <dwoo08.lee@samsung.com>
include/pass/device-notifier.h
src/pass/pass-resmon-source.c
src/pass/pass-resmon.c
src/pass/pass-resmon.h
src/pass/pass-thermal.c
src/thermal/thermal.c

index afde1fe9351f741ad3473c24e12d04b131f1e5a8..2c67f605b4eb27fcf0767098d32fba4dc4e8d369 100644 (file)
@@ -26,6 +26,7 @@ enum device_notifier_type {
        DEVICE_NOTIFIER_INIT_DONE,
        DEVICE_NOTIFIER_PMQOS,
        DEVICE_NOTIFIER_THERMAL,
+       DEVICE_NOTIFIER_THERMAL_GET_SCENARIO,
        DEVICE_NOTIFIER_MAX,
 };
 
index ac469bf580d33a426f29713a4a45ca77b052c7b5..40da8838f1a428f53652e1ba5bc2bf2385cbbdca 100644 (file)
@@ -45,6 +45,9 @@
 static int resmon_thermal_init(struct resmon *monitor)
 {
        struct resmon_result_src_thermal *result;
+       struct pass_resmon *resmon = monitor->resmon;
+       struct pass_resource *res =
+                       container_of(resmon, struct pass_resource, resmon);
 
        if (monitor->result)
                return 0;
@@ -52,6 +55,12 @@ static int resmon_thermal_init(struct resmon *monitor)
        result = calloc(1, sizeof(*result));
        if (!result)
                return -ENOMEM;
+       /*
+        * To handle GetCoolDownStatus method before the first timer of
+        * resource monitor for thermal is ticked, get current temperature
+        * in advance.
+        */
+       result->temp = pass_get_temp(res);
 
        monitor->result = result;
 
index 35fc30c1744f6c225184b6e86bc405a55e27b772..074eda8a7bf32d3703555e4a76a452f5fcccefd1 100644 (file)
@@ -284,6 +284,21 @@ static gboolean resmon_timer_func(gpointer data)
        return true;
 }
 
+void *pass_resmon_get_result(struct pass_resource *res,
+                            enum resmon_src_type src_type)
+{
+       struct resmon *monitor;
+
+       if (!res)
+               return NULL;
+
+       monitor = resmon_find_monitor(&res->resmon, RESMON_TIMER, src_type);
+       if (!monitor)
+               return NULL;
+
+       return monitor->result;
+}
+
 /**
  * @brief      Register a timer-based resource monitor.
  * @param      [in] res Instance of a resource monitor
index a3b6d8155a67df1069b51accac7d5bf43750a150..3992a313c610d129e9a19e8a84ff35547c2fc51e 100644 (file)
@@ -109,6 +109,9 @@ struct resmon_result_src_cpuhp {
        unsigned int avg_thread_runnable_load;
 };
 
+void *pass_resmon_get_result(struct pass_resource *res,
+                            enum resmon_src_type src_type);
+
 /*
  * pass_resmon_register_timer - Register timer-based resource monitor.
  *
index f47b4ed0692e02be67ac6a686103b0af3b9a8d78..ff2ebae28bb88428ef2df969decd2dd375c445a6 100644 (file)
@@ -125,6 +125,51 @@ static int thermal_monitor_func(void *result, void *user_data)
        return 0;
 }
 
+static inline void *get_thermal_result(struct pass_resource *res)
+{
+       return pass_resmon_get_result(res, RESMON_SRC_THERMAL);
+}
+
+static int thermal_get_scenario(void **scenario, void *user_data)
+{
+       struct pass_resource *res = user_data;
+       struct resmon_result_src_thermal *thermal_result;
+       struct pass_thermal *thermal;
+       int curr_temp, temp;
+       int i, scenario_idx;
+
+       if (!res) {
+               _E("invalid parameter\n");
+               return -EINVAL;
+       }
+
+       thermal = &res->thermal;
+
+       thermal_result = get_thermal_result(res);
+       if (!thermal_result)
+               return -EINVAL;
+
+       curr_temp = thermal_result->temp;
+
+       for (i = thermal->num_scenarios - 1; i > 0; i--) {
+               temp = thermal->scenarios[i].thermal.temperature;
+
+               if (thermal->scenarios[i].state != PASS_ON)
+                       continue;
+
+               if (temp <= curr_temp)
+                       break;
+       }
+       scenario_idx = i;
+
+       *scenario = (void *)thermal->scenarios[scenario_idx].name;
+
+       thermal->curr_temp = curr_temp;
+       thermal->curr_scenario_idx = scenario_idx;
+
+       return 0;
+}
+
 /**
  * @brief      Initialize PASS_MODULE_THERMAL(Thermal Monitor) module.
  * @param      [in] res Instance of h/w resource
@@ -170,8 +215,20 @@ int pass_thermal_init(struct pass_resource *res)
        res->thermal.curr_scenario_idx = -1;
        res->thermal.curr_temp = DEFAULT_TEMPERATURE;
 
+       ret = register_notifier(DEVICE_NOTIFIER_THERMAL_GET_SCENARIO,
+                               thermal_get_scenario, res);
+       if (ret < 0) {
+               _E("failed to register a notifier callback\n");
+               goto err_uevent;
+       }
+
        return 0;
 
+err_uevent:
+       ret = pass_resmon_unregister_uevent(res, RESMON_SRC_THERMAL);
+       if (ret < 0)
+               _E("failed to unregister uevent-based monitor\n");
+
 err_timer:
        ret = pass_resmon_unregister_timer(res, RESMON_SRC_THERMAL);
        if (ret < 0) {
@@ -197,6 +254,11 @@ int pass_thermal_exit(struct pass_resource *res)
        if (res->thermal.state != PASS_ON)
                return 0;
 
+       ret = unregister_notifier(DEVICE_NOTIFIER_THERMAL_GET_SCENARIO,
+                                 thermal_get_scenario, res);
+       if (ret < 0)
+               _E("failed to unregister a notifier callback\n");
+
        ret = pass_resmon_unregister_uevent(res, RESMON_SRC_THERMAL);
        if (ret < 0) {
                _E("failed to unregister uevent-based monitor " \
index 18c8eea6d4c09333866bfa80743ac12ac10eaf04..fc6b0a9fee3150426974557004ba6fc8113d17a9 100644 (file)
@@ -104,8 +104,8 @@ static void thermal_free(void)
  */
 static int thermal_init_done(void *data, void *user_data)
 {
-       int ret;
-       int i;
+       char *scenario = NULL;
+       int ret, i;
 
        if (g_thermal)
                return 0;
@@ -134,12 +134,42 @@ static int thermal_init_done(void *data, void *user_data)
                return ret;
        }
 
-       g_thermal->cur_scenario_idx = -1;
-
        for (i = 0; i < g_thermal->num; i++)
                if (g_thermal->list[i].support)
                        _I("Support \'%s\' scenario", g_thermal->list[i].name);
 
+       device_notify(DEVICE_NOTIFIER_THERMAL_GET_SCENARIO, &scenario);
+
+       if (!scenario) {
+               _E("failed to get current scenario for thermal\n");
+               free(g_thermal);
+               g_thermal = NULL;
+               return -EINVAL;
+       }
+
+       for (i = 0; i < g_thermal->num; i++) {
+               if (!g_thermal->list[i].support)
+                       continue;
+               if (!strncmp(g_thermal->list[i].name,
+                               scenario, strlen(scenario)))
+                       break;
+       }
+
+       if (i >= g_thermal->num) {
+               _E("failed to match current thermal scenario");
+
+               ret = thermal_put_scenario(g_thermal);
+               if (ret < 0) {
+                       _E("failed to put Thermal Monitor scenario\n");
+                       free(g_thermal);
+                       g_thermal = NULL;
+               }
+
+               return -EINVAL;
+       }
+
+       g_thermal->cur_scenario_idx = i;
+
        return 0;
 }