}
/*
- * pass_notifier_booting_done - Callback func of DEVICE_NOTIFIER_BOOTING_DONE
- * @data: NULL, this parameter isn't used
- * @user_data: the instance of struct pass_policy
- */
-static int pass_notifier_booting_done(void *data, void *user_data)
-{
- struct pass_policy *policy = user_data;
-
- /* Start PASS governor if 'pass_support' in pass.conf is true */
- if (policy->state == PASS_ON)
- pass_governor_update(policy, PASS_GOV_START);
-
- return 0;
-}
-
-/*
* pass_notifier_pmqos - Callback func of DEVICE_NOTIFIER_PMQOS
* @data: the scenario name
* @user_data: the instance of struct pass_policy
/* Register DEVICE_NOTIFIER_PMQOS */
register_notifier(DEVICE_NOTIFIER_PMQOS, pass_notifier_pmqos, policy);
- /* Register DEVICE_NOTIFIER_BOOTING_DONE */
- register_notifier(DEVICE_NOTIFIER_BOOTING_DONE,
- pass_notifier_booting_done, policy);
-
return 0;
}
/* Un-register DEVICE_NOTIFIER_PMQOS */
unregister_notifier(DEVICE_NOTIFIER_PMQOS, pass_notifier_pmqos);
- /* Un-Register DEVICE_NOTIFIER_BOOTING_DONE */
- unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE,
- pass_notifier_booting_done);
-
return 0;
}
/* Set default PASS state */
policy->gov_state = PASS_GOV_STOP;
-
- /* Initialize notifier */
pass_notifier_init(policy);
_I("Initialize governor for '%s' resource", cdata->res_name);
+ if (policy->state == PASS_ON)
+ pass_governor_update(policy, PASS_GOV_START);
+
return 0;
}
#include "pass-hal.h"
#include "pass-gov.h"
+#include "core/device-notifier.h"
#include "core/devices.h"
#include "core/common.h"
#include "core/edbus-handler.h"
+#define PASS_CONF_PATH "/etc/pass/pass.conf"
#define PASS_DEFAULT_MIN_LEVEL 0
#define PASS_DEFAULT_CPU_THRESHOLD 20
#define PASS_DEFAULT_LEVEL_UP_THRESHOLD 30
static struct pass g_pass;
/******************************************************
+ * PASS interfaces: Probe/Init/Exit *
+ * (Declarations) *
+ ******************************************************/
+static int pass_probe(void *data);
+static void pass_init(void *data);
+static int pass_init_done(void *data, void *user_data);
+static void pass_exit(void *data);
+static int pass_exit_done(void);
+
+/******************************************************
* PASS D-Bus interface *
******************************************************/
static DBusMessage* e_dbus_start_cb(E_DBus_Object *obj, DBusMessage* msg)
{
DBusMessage *ret_dbus = NULL;
- int i, ret;
-
- for (i = 0; i < g_pass.num_resources; i++) {
- struct pass_resource *pass_res = &g_pass.res[i];
- struct pass_policy *policy = &pass_res->policy;
+ int ret;
- ret = pass_governor_update(policy, PASS_GOV_START);
- if (ret < 0) {
- _E("cannot start the governor with dbus");
- return ret_dbus;
- }
- ret_dbus = dbus_message_new_method_return(msg);
- if (!ret_dbus)
- return ret_dbus;
+ ret = pass_init_done(NULL, NULL);
+ if (ret < 0) {
+ _E("failed to initialize the daemon in dbus callback \
+ for a start message\n");
+ return ret_dbus;
}
+ ret_dbus = dbus_message_new_method_return(msg);
return ret_dbus;
}
static DBusMessage* e_dbus_stop_cb(E_DBus_Object *obj, DBusMessage* msg)
{
DBusMessage *ret_dbus = NULL;
- int i, ret;
-
- for (i = 0; i < g_pass.num_resources; i++) {
- struct pass_resource *pass_res = &g_pass.res[i];
- struct pass_policy *policy = &pass_res->policy;
-
- ret = pass_governor_update(policy, PASS_GOV_STOP);
- if (ret < 0) {
- _E("cannot stop the governor");
- return ret_dbus;
- }
+ int ret;
- ret_dbus = dbus_message_new_method_return(msg);
- if (!ret_dbus)
- return ret_dbus;
+ ret = pass_exit_done();
+ if (ret < 0) {
+ _E("failed to exit the daemon in dbus callback \
+ for a stop message\n");
+ return ret_dbus;
}
+ ret_dbus = dbus_message_new_method_return(msg);
return ret_dbus;
}
return 0;
}
-/*
- * pass_init - Initialize PASS(Power Aware System Service)
- *
- * @data: the instance of structre pass_policy
- */
-
-static void pass_init(void *data)
+static int pass_init_done(void *data, void *user_data)
{
int i, ret;
+ /* Parse configuration file (/etc/pass/pass.conf) */
+ ret = pass_parse_resource(&g_pass, PASS_CONF_PATH);
+ if (ret < 0) {
+ _E("cannot parse %s\n", PASS_CONF_PATH);
+ return ret;
+ }
+
+ /* Initialize pass resources data based on parsed configuration */
+ ret = pass_get_resource(&g_pass);
+ if (ret < 0) {
+ _E("cannot get the pass resource\n");
+ return ret;
+ }
+
for (i = 0; i < g_pass.num_resources; i++) {
struct pass_resource *pass_res = &g_pass.res[i];
struct pass_policy *policy = &pass_res->policy;
_I("Resource%d first cpu : %d\n\n", i, cdata->cpu);
}
- /*
- * Initialzie D-Bus interface of PASS. User can be able to
- * turn on/off PASS through D-Bus interface.
- */
- ret = register_edbus_method(PASS_PATH_CORE, edbus_methods,
- ARRAY_SIZE(edbus_methods));
- if (ret < 0) {
- _I("cannot initialize PASS D-Bus (%d)", ret);
- return;
- }
-
for (i = 0; i < g_pass.num_resources; i++) {
struct pass_resource *pass_res = &g_pass.res[i];
struct pass_policy *policy = &pass_res->policy;
ret = pass_resource_init(policy);
if (ret < 0) {
_E("cannot initialize the pass resource\n");
- return;
+ pass_exit(NULL);
+ return -EINVAL;
}
}
+
+ return 0;
}
-/*
- * pass_exit - Exit PASS
- *
- * @data: the instance of structre pass_policy
- */
-static void pass_exit(void *data)
+static int pass_exit_done(void)
{
int i, ret;
+ ret = 0;
for (i = 0; i < g_pass.num_resources; i++) {
struct pass_resource *pass_res = &g_pass.res[i];
struct pass_policy *policy = &pass_res->policy;
ret = pass_resource_exit(policy);
if (ret < 0) {
- _E("cannot exit the pass resource");
+ _E("failed to clean up the pass resource #%d\n", i);
+ break;
}
}
+
+ return ret;
}
-int pass_probe(void *data)
+/*
+ * pass_init - Initialize PASS(Power Aware System Service)
+ *
+ * @data: When the data is passed from pass_main(), it is NULL.
+ * On the other hand, it will contain the result of this function
+ */
+static void pass_init(void *data)
+{
+ /* This is the only case of daemon creation: DO NOTHING */
+}
+
+/*
+ * pass_exit - Exit PASS
+ *
+ * @data: When the data is passed from pass_main(), it is NULL.
+ * On the other hand, it will contain the result of this function
+ */
+static void pass_exit(void *data)
{
int ret;
+ unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, pass_init_done);
+
+ ret = pass_exit_done();
+ if (ret < 0) {
+ _E("cannot exit PASS daemon\n");
+ return;
+ }
+
+ _I("exit PASS daemon without any errors\n");
+}
+
+/*
+ * pass_probe - Probe PASS
+ *
+ * @data: the data passed from pass_main(), currently NULL
+ */
+static int pass_probe(void *data)
+{
+ int ret = 0;
+
/*
- * Initialize pass resources data by parsing pass.conf
+ * Register methods to D-Bus interface of PASS. By using it,
+ * user can turn on/off PASS
*/
- ret = pass_parse_resource(&g_pass, "/etc/pass/pass.conf");
+ ret = register_edbus_method(PASS_PATH_CORE, edbus_methods,
+ ARRAY_SIZE(edbus_methods));
if (ret < 0) {
- _E("cannot parse /etc/pass/pass.conf\n");
+ _E("cannot register dbus methods required \
+ to control the daemon (%d)\n", ret);
return ret;
}
- ret = pass_get_resource(&g_pass);
+ /*
+ * Register a notifier for the booting-done event. The actual
+ * initialization of the daemon is performed by this notifier after
+ * booting is completely done.
+ */
+ ret = register_notifier(DEVICE_NOTIFIER_BOOTING_DONE,
+ pass_init_done, NULL);
if (ret < 0) {
- _E("cannot get the pass resource\n");
+ _E("cannot register a callback function \
+ for the booting-done event (%d)\n", ret);
return ret;
}
- return 0;
+ return ret;
}
static const struct device_ops pass_device_ops = {