pass: Add support of cooling-device property 56/262156/1
authorChanwoo Choi <cw00.choi@samsung.com>
Tue, 3 Aug 2021 06:19:23 +0000 (15:19 +0900)
committerChanwoo Choi <cw00.choi@samsung.com>
Tue, 3 Aug 2021 06:21:27 +0000 (15:21 +0900)
Already thermal monitor in pass get the thermal information with
'thermal_device_name' property. When over-temperature is deteced,
must need to prevent the dangerous situation by using the cooling-device
which is attached to a thermal device.

So that add 'cooling_device_name' property in 'device_list' section
in order to get/set the information of cooling-device.
Also, 'thermal,cooling_device_state' property will be used
when try to change the state of cooling-device if over-temperature is
detected.

Lastly, enable thermal operation for both new PASS_RESOURCE_BATTERY_ID devie type
and PASS_RESOURCE_NONSTANDARD_ID.

[Newly added properties for cooling-device]
- 'cooling_device_name' property in 'device_list' section
- 'thermal,cooling_device_state' property in 'level_list' section

[Example of cooling-device properties]
In case of scripts/pass.json,
                        "device_name"           : "cpu0",
                        "device_config_path"    : "/hal/etc/pass/pass-cpu0.json",
                        "thermal_device_name"   : "thermal_zone0",
                        "cooling_device_name"   : "cooling_device0", <- Added
                        "cpu,number_of_cpus"    : 4,
                        "cpu,first_cpu"         : 0,

In case of scripts/pass-cpu0.json,
                {
                        "level"                         : 0,
                        "dvfs,minimum_frequency_khz"    : 600000,
                        "dvfs,maximum_frequency_khz"    : 1500000,
                        "thermal,cooling_device_state"  : 0 <- Added
                }, {
                        "level"                         : 1,
                        "dvfs,minimum_frequency_khz"    : 1500000,
                        "dvfs,maximum_frequency_khz"    : 1500000,
                        "thermal,cooling_device_state"  : 1 <- Added
                },

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

index f2229f7924daf306467be0724ea2758aa9a4d4e7..98e5ec6e1aaa27a3b103df94430899f6f44350f5 100644 (file)
@@ -401,6 +401,74 @@ int pass_hal_get_tmu_policy(struct pass_resource *res, char *policy)
                                        policy);
 }
 
+/**
+ * @brief      Get the state of cooling_device for h/w resource
+ * @param      [in] res Instance of h/w resource
+ * @return     @c positive integer on success, otherwise error value
+ * @retval     -22 Invalid argument (-EINVAL)
+ * @retval     -1 Operation not permitted (-EPERM)
+ * @retval     -19 Operation not supported (-ENOTSUP)
+ */
+int pass_hal_get_cooling_device_state(struct pass_resource *res)
+{
+       if (!res)
+               return -EINVAL;
+
+       /*
+        * In the case of the HAL TMU ops, res_cooling_name is used
+        * as the first argument instead of res_name.
+        */
+       return hal_power_thermal_get_cooling_device_state(
+                                       res->config_data.res_type,
+                                       res->config_data.res_cooling_name);
+}
+
+/**
+ * @brief      Set the state to cooling_device for h/w resource
+ * @param      [in] res Instance of h/w resource
+ * @param      [in] state State of cooling device
+ * @return     @c positive integer on success, otherwise error value
+ * @retval     -22 Invalid argument (-EINVAL)
+ * @retval     -1 Operation not permitted (-EPERM)
+ * @retval     -19 Operation not supported (-ENOTSUP)
+ */
+int pass_hal_set_cooling_device_state(struct pass_resource *res, int state)
+{
+       if (!res)
+               return -EINVAL;
+
+       /*
+        * In the case of the HAL TMU ops, res_cooling_name is used
+        * as the first argument instead of res_name.
+        */
+       return hal_power_thermal_set_cooling_device_state(
+                                       res->config_data.res_type,
+                                       res->config_data.res_cooling_name,
+                                       state);
+}
+
+/**
+ * @brief      Get the maximum state of cooling_device for h/w resource
+ * @param      [in] res Instance of h/w resource
+ * @return     @c positive integer on success, otherwise error value
+ * @retval     -22 Invalid argument (-EINVAL)
+ * @retval     -1 Operation not permitted (-EPERM)
+ * @retval     -19 Operation not supported (-ENOTSUP)
+ */
+int pass_hal_get_cooling_device_max_state(struct pass_resource *res)
+{
+       if (!res)
+               return -EINVAL;
+
+       /*
+        * In the case of the HAL TMU ops, res_cooling_name is used
+        * as the first argument instead of res_name.
+        */
+       return hal_power_thermal_get_cooling_device_max_state(
+                                       res->config_data.res_type,
+                                       res->config_data.res_cooling_name);
+}
+
 /**
  * @brief      Set the fault_around_bytes for memory h/w resource
  * @param      [in] res Instance of h/w resource
index 43b45e32312bac9269dbdf8f768f1e9a0cdd44f8..f5e2f264db669a256a3e52d08fca6b1a301df545 100644 (file)
@@ -76,6 +76,11 @@ int pass_hal_set_up_threshold(struct pass_resource *res, int up_threshold);
 int pass_hal_get_temp(struct pass_resource *res);
 int pass_hal_get_tmu_policy(struct pass_resource *res, char *policy);
 
+/* Get and set the state of cooling device on specific h/w. */
+int pass_hal_get_cooling_device_state(struct pass_resource *res);
+int pass_hal_set_cooling_device_state(struct pass_resource *res, int state);
+int pass_hal_get_cooling_device_max_state(struct pass_resource *res);
+
 /***
  * Functions for CPU H/W resources
  */
index 77ebfd4927f46cea6836f1fe5da5940347ad8710..9f3f902e50d933074f951b7649bcfc58a4fd000b 100644 (file)
@@ -213,6 +213,8 @@ static void initialize_level(struct pass_level *level)
        level->gov_timeout = INIT_VALUE;
 
        level->fault_around_bytes = INIT_VALUE;
+
+       level->cooling_device_state = INIT_VALUE;
 }
 
 static int parse_level(struct pass_resource *res, json_object *obj,
@@ -241,6 +243,7 @@ static int parse_level(struct pass_resource *res, json_object *obj,
        int num_left_cond_busy_cpu;
        double governor_timeout_sec;
        int fault_around_bytes;
+       int cooling_device_state;
 
        /* Get property values */
        level = get_int_from_object(obj, "level");
@@ -273,6 +276,8 @@ static int parse_level(struct pass_resource *res, json_object *obj,
 
        fault_around_bytes = get_int_from_object(obj, "memory,fault_around_bytes");
 
+       cooling_device_state = get_int_from_object(obj, "thermal,cooling_device_state");
+
        /* Check the mandatory property values are valid or not */
        if (level < 0) {
                _E("Failed to get 'level' property in 'level_list' section\n");
@@ -355,6 +360,17 @@ static int parse_level(struct pass_resource *res, json_object *obj,
        if (fault_around_bytes >= 0)
                target_level->fault_around_bytes = fault_around_bytes;
 
+       /*
+        * Properties for the following h/w resources:
+        * - PASS_RESOURCE_CPU_ID
+        * - PASS_RESOURCE_BUS_ID
+        * - PASS_RESOURCE_GPU_ID
+        * - PASS_RESOURCE_BATTERY_ID
+        * - PASS_RESOURCE_NONSTANDARD_ID
+        */
+       if (cooling_device_state >= 0)
+               target_level->cooling_device_state = cooling_device_state;
+
        return 0;
 }
 
@@ -669,6 +685,7 @@ static int parse_resource_data(struct pass *pass, int id, json_object *obj)
        const char *device_type;
        const char *device_name;
        const char *thermal_device_name;
+       const char *cooling_device_name;
        const char *device_config_path;
        const char *cpu_load_path;
        int number_of_cpus;
@@ -682,6 +699,7 @@ static int parse_resource_data(struct pass *pass, int id, json_object *obj)
 
        /* - optional properties */
        thermal_device_name = get_string_from_object(obj, "thermal_device_name");
+       cooling_device_name = get_string_from_object(obj, "cooling_device_name");
 
        /* - optional properties for only CPU */
        cpu_load_path = get_string_from_object(obj, "cpu,cpu_load_path");
@@ -733,6 +751,7 @@ static int parse_resource_data(struct pass *pass, int id, json_object *obj)
 
        snprintf(config_data->res_name, BUFF_MAX, "%s", device_name);
        snprintf(config_data->res_thermal_name, BUFF_MAX, "%s", thermal_device_name);
+       snprintf(config_data->res_cooling_name, BUFF_MAX, "%s", cooling_device_name);
        snprintf(config_data->path_conf_file, BUFF_MAX, "%s", device_config_path);
        snprintf(config_data->path_load_table, BUFF_MAX, "%s", cpu_load_path);
        config_data->num_cpus = number_of_cpus;
index 0d96475727ea92a0ed2cc5692e19f972e244c160..5e9b0edc060168dbb82abc2b9e22d465d620bd04 100644 (file)
@@ -73,6 +73,13 @@ static void rescon_print_level(struct pass_resource *res,
                                level->fault_around_bytes,
                                res->config_data.res_name);
        }
+
+       if (level->cooling_device_state >= 0) {
+               _D("cooling_device_state is %10d of '%s' resource\n",
+                               level->cooling_device_state,
+                               res->config_data.res_name);
+       }
+
 }
 
 static void rescon_adjust_level(struct pass_level *a, struct pass_level *b)
@@ -101,6 +108,10 @@ static void rescon_adjust_level(struct pass_level *a, struct pass_level *b)
                if (a->fault_around_bytes > MAX_FAULT_AROUND_BYTES)
                        a->fault_around_bytes = MAX_FAULT_AROUND_BYTES;
        }
+
+       /* Adjust cooling_device_state */
+       a->cooling_device_state = MAX(a->cooling_device_state,
+                                       b->cooling_device_state);
 }
 
 static int rescon_update(struct pass_resource *res)
@@ -116,6 +127,7 @@ static int rescon_update(struct pass_resource *res)
        int limit_min_cpu = -1;
        int limit_max_cpu = -1;
        int fault_around_bytes = -1;
+       int cooling_device_state = -1;
        int ret, i;
        int failed = 0;
 
@@ -130,6 +142,7 @@ static int rescon_update(struct pass_resource *res)
        adjusted_level.limit_min_cpu = MIN_INT;
        adjusted_level.limit_max_cpu = MAX_INT;
        adjusted_level.fault_around_bytes = MIN_INT;
+       adjusted_level.cooling_device_state = MIN_INT;
 
        /* Adjust with pass_level */
        if (res->rescon.curr_level >= 0)
@@ -156,12 +169,14 @@ static int rescon_update(struct pass_resource *res)
        case PASS_RESOURCE_BUS_ID:
                limit_max_freq = adjusted_level.limit_max_freq;
                limit_min_freq = adjusted_level.limit_min_freq;
+               /* fall through */
+       case PASS_RESOURCE_BATTERY_ID:
+       case PASS_RESOURCE_NONSTANDARD_ID:
+               cooling_device_state = adjusted_level.cooling_device_state;
                break;
        case PASS_RESOURCE_MEMORY_ID:
                fault_around_bytes = adjusted_level.fault_around_bytes;
                break;
-       case PASS_RESOURCE_NONSTANDARD_ID:
-               break;
        default:
                return -EINVAL;
        }
@@ -262,6 +277,17 @@ static int rescon_update(struct pass_resource *res)
                }
        }
 
+       /* Set cooling device state for specific h/w */
+       if (cooling_device_state >= 0) {
+               ret = pass_hal_set_cooling_device_state(res, cooling_device_state);
+               if (ret < 0) {
+                       _W("failed to set the cooling_device_state(%d) of %s",
+                                               cooling_device_state,
+                                               res->config_data.res_name);
+                       failed = 1;
+               }
+       }
+
        if (!failed)
                rescon_print_level(res, &adjusted_level);
        else
index a92513f52a5ad9b91755719ce28a64d00e9e8d53..e8d28d27a24761e13bb4acbb9814bdec3cab0449 100644 (file)
@@ -376,6 +376,7 @@ static int pass_init_done(void *data, void *user_data)
                _I("Resource%d type           : %d\n", i, config_data->res_type);
                _I("Resource%d name           : %s\n", i, config_data->res_name);
                _I("Resource%d thermal name   : %s\n", i, config_data->res_thermal_name);
+               _I("Resource%d cooling name   : %s\n", i, config_data->res_cooling_name);
                _I("Resource%d path_conf_file : %s\n", i, config_data->path_conf_file);
                _I("Resource%d path_load_table: %s\n", i, config_data->path_load_table);
                _I("Resource%d number of cpus : %d\n", i, config_data->num_cpus);
index 2bf4a935c71ce1e64c57d94eb3c3485b04769a33..cb910c9a969b5069e776f6fc2b72f7e04117df74 100644 (file)
@@ -150,7 +150,16 @@ struct pass_level {
         * - PASS_RESOURCE_MEMORY_ID
         */
        int fault_around_bytes;
-
+       /**
+        * The current state of cooling device
+        * and this property is used for the following resources:
+        * - PASS_RESOURCE_CPU_ID
+        * - PASS_RESOURCE_BUS_ID
+        * - PASS_RESOURCE_GPU_ID
+        * - PASS_RESOURCE_BATTERY_ID
+        * - PASS_RESOURCE_NONSTANDARD_ID
+        */
+       int cooling_device_state;
 
        /* Properties for the timer */
 
@@ -438,6 +447,13 @@ struct pass_resource_config_data {
         *   res_thermal_name is 'thermal_zone3'.
         */
        char res_thermal_name[BUFF_MAX];
+       /**
+        * [optional] the unique sysfs node name of cooling device for each resource
+        * - In the case of 'cpu0',
+        *   If sysfs node of cooling device is /sys/class/thermal/cooling_device0,
+        *   res_cooling_name is 'cooling_device0'.
+        */
+       char res_cooling_name[BUFF_MAX];
        /** [mandatory] Path fo configuration for each h/w resource */
        char path_conf_file[BUFF_MAX];