2 * PASS (Power Aware System Service)
4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
26 #include "pass-core.h"
27 #include "pass-target.h"
29 #include "core/devices.h"
30 #include "core/common.h"
31 #include "core/edbus-handler.h"
33 #define PASS_DEFAULT_MIN_LEVEL 0
34 #define PASS_DEFAULT_CPU_THRESHOLD 20
35 #define PASS_DEFAULT_LEVEL_UP_THRESHOLD 30
36 #define PASS_DEFAULT_LEVEL_DOWN_THRESHOLD 80
39 * Per-target pass policy
41 static struct pass_policy policy;
43 /******************************************************
44 * PASS D-Bus interface *
45 ******************************************************/
46 static DBusMessage* e_dbus_start_cb(E_DBus_Object *obj, DBusMessage* msg)
49 policy.governor->update(&policy, PASS_GOV_START);
50 return dbus_message_new_method_return(msg);
53 static DBusMessage* e_dbus_stop_cb(E_DBus_Object *obj, DBusMessage* msg)
56 policy.governor->update(&policy, PASS_GOV_STOP);
57 return dbus_message_new_method_return(msg);
60 static const struct edbus_method edbus_methods[] = {
61 { "start", NULL, NULL, e_dbus_start_cb },
62 { "stop", NULL, NULL, e_dbus_stop_cb },
65 /******************************************************
66 * PASS interface (Init/Exit) *
67 ******************************************************/
70 * pass_init - Initialize PASS(Power Aware System Service)
72 * @data: the instance of structre pass_policy
74 static void pass_init(void *data)
76 enum pass_target_type target_type;
83 * Initialize pass-table by parsing pass.conf
85 ret = get_pass_table(&policy, PASS_CONF_PATH);
87 _E("cannot parse %s\n", PASS_CONF_PATH);
92 * Initialzie D-Bus interface of PASS. User can be able to
93 * turn on/off PASS through D-Bus interface.
95 ret = register_edbus_method(DEVICED_PATH_PASS, edbus_methods,
96 ARRAY_SIZE(edbus_methods));
98 _I("cannot initialize PASS D-Bus (%d)", ret);
102 /* Check whether PASS is initialzied state or not */
103 if (policy.governor) {
104 _I("PASS is already active state");
109 * Set default value to global pass_policy instance
110 * if variable isn't initialized.
112 if (!policy.min_level)
113 policy.min_level = PASS_DEFAULT_MIN_LEVEL;
114 policy.default_min_level = policy.min_level;
116 if (!policy.max_level)
117 policy.max_level = policy.num_levels - 1;
118 policy.default_max_level = policy.max_level;
120 if (!policy.init_level)
121 policy.init_level = PASS_DEFAULT_MIN_LEVEL;
123 if (!policy.pass_cpu_threshold)
124 policy.pass_cpu_threshold = PASS_DEFAULT_CPU_THRESHOLD;
126 if (!policy.up_threshold)
127 policy.up_threshold = PASS_DEFAULT_LEVEL_UP_THRESHOLD;
129 if (!policy.down_threshold)
130 policy.down_threshold = PASS_DEFAULT_LEVEL_DOWN_THRESHOLD;
132 if (!policy.level_up_threshold)
133 policy.level_up_threshold = policy.max_level;
135 if (!policy.num_pass_cpu_stats)
136 policy.num_pass_cpu_stats = PASS_CPU_STATS_DEFAULT;
138 for (i = 0; i < policy.num_levels; i++) {
139 if (max_freq < policy.pass_table[i].limit_max_freq)
140 max_freq = policy.pass_table[i].limit_max_freq;
141 if (max_cpu < policy.pass_table[i].limit_max_cpu)
142 max_cpu = policy.pass_table[i].limit_max_cpu;
144 policy.cpufreq.max_freq = max_freq;
145 policy.cpufreq.num_nr_cpus = max_cpu;
147 /* Allocate memory according to the number of data and cpu */
148 policy.pass_cpu_stats = malloc(sizeof(struct pass_cpu_stats)
149 * policy.num_pass_cpu_stats);
151 for (i = 0; i < policy.num_pass_cpu_stats; i++) {
152 policy.pass_cpu_stats[i].load =
153 malloc(sizeof(unsigned int) * policy.cpufreq.num_nr_cpus);
154 policy.pass_cpu_stats[i].nr_running =
155 malloc(sizeof(unsigned int) * policy.cpufreq.num_nr_cpus);
156 policy.pass_cpu_stats[i].runnable_load =
157 malloc(sizeof(unsigned int) * policy.cpufreq.num_nr_cpus);
160 /* Get the instance of PASS governor */
161 policy.governor = pass_get_governor(&policy, policy.gov_type);
162 if (!policy.governor) {
163 _E("cannot get the instance of PASS governor");
166 policy.governor->gov_timeout = policy.gov_timeout;
168 /* Get the instance of PASS hotplulg */
169 policy.hotplug = pass_get_hotplug(&policy, policy.gov_type);
170 if (!policy.hotplug) {
171 _E("cannot get the instance of PASS hotplug");
173 policy.hotplug->sequence = malloc(sizeof(int)
174 * policy.cpufreq.num_nr_cpus);
175 for (i = 0; i < policy.cpufreq.num_nr_cpus; i++)
176 policy.hotplug->sequence[i] = i;
179 if (policy.governor->init) {
180 ret = policy.governor->init(&policy);
182 _E("cannot initialize PASS governor");
186 _E("cannot execute init() of PASS governor");
192 * pass_exit - Exit PASS
194 * @data: the instance of structre pass_policy
196 static void pass_exit(void *data)
200 if (!policy.governor) {
201 _E("cannot exit PASS");
205 put_pass_table(&policy);
207 if (policy.governor->exit) {
208 ret = policy.governor->exit(&policy);
210 _E("cannot exit PASS governor");
214 _E("cannot execute exit() of PASS governor");
218 policy.governor = NULL;
221 static const struct device_ops pass_device_ops = {
222 .priority = DEVICE_PRIORITY_NORMAL,
228 DEVICE_OPS_REGISTER(&pass_device_ops)