2e3c1a2de038078ed687e971e6e8e8fc3a584fb0
[platform/core/system/deviced.git] / src / display / display.c
1 /*
2  * deviced
3  *
4  * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  */
18 #include <fnmatch.h>
19 #include <signal.h>
20
21 #include <libsyscommon/list.h>
22 #include <libsyscommon/resource-manager.h>
23 #include <system/syscommon-plugin-deviced-power-interface.h>
24 #include <system/syscommon-plugin-deviced-common-interface.h>
25 #include <system/syscommon-plugin-deviced-display.h>
26 #include <shared/devices.h>
27
28 #include "core/udev.h"
29 #include "shared/device-notifier.h"
30 #include "shared/log.h"
31 #include "power/power.h"
32 #include "power/power-suspend.h"
33 #include "power/power-boot.h"
34 #include "device-interface.h"
35 #include "display.h"
36 #include "display-lock.h"
37 #include "display-plugin.h"
38 #include "display-config.h"
39 #include "display-misc.h"
40 #include "display-ops.h"
41 #include "display-signal.h"
42 #include "display-state-transition.h"
43 #include "lock-detector.h"
44
45 #define DELAYED_INIT_WATING_TIME        60000   /* 1 minute */
46
47 static const struct device_ops *display_plugin_device_ops;
48 static unsigned int pm_status_flag;
49 static enum syscommon_deviced_display_orientation g_display_init_direction;
50 static bool g_display_hal_backend_available = false;
51 static GList *display_dependent_device_ops;
52 static enum device_ops_status display_ops_status = DEVICE_OPS_STATUS_UNINIT;
53 static struct syscommon_deviced_display_state_info default_states[SYSCOMMON_DEVICED_DISPLAY_STATE_END] = {
54         { SYSCOMMON_DEVICED_DISPLAY_STATE_START,    "SYSCOMMON_DEVICED_DISPLAY_STATE_START",    NULL,          NULL,           NULL,          NULL            },
55         { SYSCOMMON_DEVICED_DISPLAY_STATE_ON,   "SYSCOMMON_DEVICED_DISPLAY_STATE_ON",   NULL,          NULL,           NULL,          NULL            },
56         { SYSCOMMON_DEVICED_DISPLAY_STATE_DIM,   "SYSCOMMON_DEVICED_DISPLAY_STATE_DIM",   NULL,          NULL,           NULL,          NULL            },
57         { SYSCOMMON_DEVICED_DISPLAY_STATE_OFF,   "SYSCOMMON_DEVICED_DISPLAY_STATE_OFF",   NULL,          NULL,           NULL,          NULL            },
58         { SYSCOMMON_DEVICED_DISPLAY_STATE_SLEEP,    "SYSCOMMON_DEVICED_DISPLAY_STATE_SLEEP",    NULL,          NULL,           NULL,          NULL            },
59 };
60
61 extern void init_save_userlock(void);
62
63 inline unsigned int get_pm_status_flag(void)
64 {
65         return pm_status_flag;
66 }
67
68 inline void set_pm_status_flag(unsigned int status_flag)
69 {
70         pm_status_flag |= status_flag;
71 }
72
73 inline void clear_pm_status_flag(unsigned int status_flag)
74 {
75         pm_status_flag &= ~status_flag;
76 }
77
78 inline enum syscommon_deviced_display_orientation get_display_init_direction(void)
79 {
80         return g_display_init_direction;
81 }
82
83 inline void set_display_init_direction(enum syscommon_deviced_display_orientation display_init_direction)
84 {
85         g_display_init_direction = display_init_direction;
86 }
87
88 void lcd_direct_control(enum syscommon_deviced_dpms_state dpms_state, int flags)
89 {
90         const struct device_ops *ops = NULL;
91         GList *l = NULL;
92
93         switch (dpms_state) {
94         case SYSCOMMON_DEVICED_DPMS_ON:
95                 SYS_G_LIST_FOREACH(display_dependent_device_ops, l, ops)
96                         ops->start(flags);
97                 break;
98         case SYSCOMMON_DEVICED_DPMS_OFF:
99                 SYS_G_LIST_FOREACH(display_dependent_device_ops, l, ops)
100                         ops->stop(flags);
101                 break;
102         default:
103                 _E("state is wrong value %d", dpms_state);
104                 break;
105         }
106 }
107
108 bool display_is_hal_backend_available(void)
109 {
110         return g_display_hal_backend_available;
111 }
112
113 void display_start_dependent_device(unsigned long flags)
114 {
115         const struct device_ops *ops = NULL;
116         GList *l;
117
118         SYS_G_LIST_FOREACH(display_dependent_device_ops, l, ops)
119                 ops->start(flags);
120 }
121
122 void display_stop_dependent_device(unsigned long flags)
123 {
124         const struct device_ops *ops = NULL;
125         GList *l;
126
127         SYS_G_LIST_FOREACH(display_dependent_device_ops, l, ops)
128                 ops->stop(flags);
129 }
130
131 void display_register_dependent_device(const struct device_ops *ops)
132 {
133         SYS_G_LIST_APPEND(display_dependent_device_ops, ops);
134 }
135
136 void display_unregister_dependent_device(void)
137 {
138         GList *l = NULL;
139         GList *l_next = NULL;;
140         const struct device_ops *ops = NULL;
141
142         SYS_G_LIST_FOREACH_SAFE(display_dependent_device_ops, l, l_next, ops)
143                 SYS_G_LIST_REMOVE_LIST(display_dependent_device_ops, l);
144 }
145
146 /* FIXME: display_dimstay_check function should be changed to plugin api call.
147  *        Only the wearable profile had the first condition only, checking DIM_FLAG. */
148 bool display_dimstay_check(void)
149 {
150         if (pm_status_flag & DIM_FLAG)
151                 return true;
152
153         if ((pm_status_flag & PWRSV_FLAG) && !(pm_status_flag & BRTCH_FLAG))
154                 return true;
155
156         return false;
157 }
158
159 int display_initialize_display_state_timeout_from_setting(void)
160 {
161         int i;
162         int val = 0;
163         const char* state_name = NULL;
164         enum syscommon_deviced_display_state state = SYSCOMMON_DEVICED_DISPLAY_STATE_START;
165
166         for (i = 0; i < SYSCOMMON_DEVICED_DISPLAY_STATE_END; i++) {
167                 display_plugin_state_get_state_by_state_index(i, &state);
168                 switch (state) {
169                 case SYSCOMMON_DEVICED_DISPLAY_STATE_ON:
170                         get_run_timeout(&val);
171                         break;
172                 case SYSCOMMON_DEVICED_DISPLAY_STATE_DIM:
173                         get_dim_timeout(&val);
174                         break;
175                 case SYSCOMMON_DEVICED_DISPLAY_STATE_OFF:
176                         display_plugin_config_get_lcdoff_timeout(&val);
177                         break;
178                 default:
179                         /* This state doesn't need to set time out. */
180                         val = 0;
181                         break;
182                 }
183                 if (val > 0) {
184                         display_plugin_state_set_timeout(i, val);
185                 }
186
187                 display_plugin_state_get_name(i, &state_name);
188                 _I("State(%s) timeout(%d) ms", state_name, val);
189         }
190
191         return 0;
192 }
193
194 /** FIXME: display_ops_status getter/setter will be removed after plugin-core separation
195            This work should be proceeded in the display core
196 */
197 bool display_is_display_ops_started_status(void)
198 {
199         return (display_ops_status == DEVICE_OPS_STATUS_START);
200 }
201
202 void display_set_display_ops_status(enum device_ops_status dev_ops_status)
203 {
204         display_ops_status = dev_ops_status;
205 }
206
207 int display_get_display_ops_status(enum device_ops_status *dev_ops_status)
208 {
209         if (!dev_ops_status)
210                 return -EINVAL;
211
212         *dev_ops_status = display_ops_status;
213         return 0;
214 }
215
216 void display_set_power_save_mode_flag(int onoff)
217 {
218         int ret;
219         enum syscommon_deviced_display_state current;
220
221         if (display_plugin_set_power_save_mode_flag(onoff) == 0)
222                 return;
223
224         if (onoff)
225                 set_pm_status_flag(PWRSV_FLAG);
226         else
227                 clear_pm_status_flag(PWRSV_FLAG);
228
229         ret = display_state_get_current(&current);
230         if (ret < 0)
231                 return;
232
233         if (current == SYSCOMMON_DEVICED_DISPLAY_STATE_ON)
234                 display_backlight_update_by_default_brightness();
235 }
236
237 static int power_resume_from_echomem_callback(void *data)
238 {
239         int ret;
240         enum syscommon_deviced_display_state current;
241
242         ret = display_state_get_current(&current);
243         if (ret < 0)
244                 return ret;
245
246         display_plugin_set_system_wakeup_flag(true);
247         if (check_wakeup_src() == EVENT_DEVICE)
248                 /* system waked up by devices */
249                 display_state_transition_do_state_transition(current, EVENT_DEVICE);
250         else
251                 /* system waked up by user input */
252                 display_state_transition_do_state_transition(current, EVENT_INPUT);
253
254         return 0;
255 }
256
257 static int poweroff_triggered_callback(void *udata)
258 {
259         int val = (int)(intptr_t) udata;
260
261         switch (val) {
262         case VCONFKEY_SYSMAN_POWER_OFF_NONE:
263                 clear_pm_status_flag(PWROFF_FLAG);
264                 break;
265         case VCONFKEY_SYSMAN_POWER_OFF_DIRECT:
266         case VCONFKEY_SYSMAN_POWER_OFF_RESTART:
267                 set_pm_status_flag(PWROFF_FLAG);
268                 break;
269         }
270
271         return 0;
272 }
273
274 static gboolean delayed_dpms_init_done(gpointer data)
275 {
276         int timeout = 0;
277         bool timeout_enable = false;
278         int lcdoff_timeout = 0;
279         int ret;
280         enum syscommon_deviced_display_state current;
281
282         if (!display_panel_init_dpms())
283                 return G_SOURCE_CONTINUE;
284
285         ret = display_state_get_current(&current);
286         if (ret < 0)
287                 return G_SOURCE_REMOVE;
288
289         switch (current) {
290         case SYSCOMMON_DEVICED_DISPLAY_STATE_ON:
291         case SYSCOMMON_DEVICED_DISPLAY_STATE_DIM:
292                 display_panel_lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
293                 display_plugin_config_get_timeout_enable(&timeout_enable);
294                 if (timeout_enable) {
295                         display_plugin_state_get_timeout(SYSCOMMON_DEVICED_DISPLAY_STATE_ON, &timeout);
296                         /* check minimun lcd on time */
297                         if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
298                                 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
299                         display_state_transition_reset_state_transition_timeout(timeout);
300                 }
301                 break;
302         case SYSCOMMON_DEVICED_DISPLAY_STATE_OFF:
303                 display_panel_lcd_off_procedure(LCD_OFF_BY_EVENT);
304                 display_plugin_config_get_lcdoff_timeout(&lcdoff_timeout);
305                 display_state_transition_reset_state_transition_timeout(lcdoff_timeout);
306                 break;
307         default:
308                 break;
309         }
310
311         return G_SOURCE_REMOVE;
312 }
313
314 void display_add_timer_for_waiting_dpms_init(void)
315 {
316         guint id = g_timeout_add(500/* milliseconds */, delayed_dpms_init_done, NULL);
317         if (id == 0)
318                 _E("Failed to add display_panel_init_dpms timeout.");
319 }
320
321 void display_set_initial_brightness(void)
322 {
323         int ret = -1;
324         int brightness = 0;
325         int default_brightness = 0;
326
327         ret = get_setting_brightness(&brightness);
328         if (ret != 0 || (brightness < PM_MIN_BRIGHTNESS || brightness > PM_MAX_BRIGHTNESS)) {
329                 _I("Failed to read vconf value for brightness.");
330                 display_plugin_config_get_pm_default_brightness(&default_brightness);
331                 if (brightness < PM_MIN_BRIGHTNESS || brightness > PM_MAX_BRIGHTNESS) {
332                         ret = vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, default_brightness);
333                         if (ret < 0)
334                                 _E("Failed to set vconf value for lcd brightness: %d", vconf_get_ext_errno());
335                 }
336                 brightness = default_brightness;
337         }
338         _I("Set brightness(%d) from setting app.", brightness);
339         display_backlight_set_default_brightness(brightness);
340         display_backlight_set_brightness(brightness);
341 }
342
343 /* FIXME: This function should be moved to battery module after battery plguin/module refactoring */
344 void display_set_initial_battery_flag(void)
345 {
346         int ret = -1;
347         int battery_state = 0;
348
349         ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &battery_state);
350         if (ret < 0) {
351                 battery_state = VCONFKEY_SYSMAN_BAT_NORMAL;
352                 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
353         }
354
355         if (display_misc_is_low_battery_state(battery_state)) {
356                 if (!(get_pm_status_flag() & CHRGR_FLAG)) {
357                         display_set_power_save_mode_flag(true);
358                         set_pm_status_flag(LOWBT_FLAG);
359                 }
360         }
361 }
362
363 void display_set_initial_lockscreen_status(void)
364 {
365         int ret = -1;
366         int lock_state = 0;
367         int lock_screen_timeout = 0;
368
369         ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
370         if (ret < 0) {
371                 lock_state = -1;
372                 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
373         }
374         set_lock_screen_state(lock_state);
375         display_state_transition_get_lock_screen_timeout(&lock_screen_timeout);
376         if (lock_state == VCONFKEY_IDLE_LOCK) {
377                 display_plugin_state_set_timeout(SYSCOMMON_DEVICED_DISPLAY_STATE_ON, lock_screen_timeout);
378                 _I("LCD NORMAL timeout(%d ms) is set for lock screen.", lock_screen_timeout);
379         }
380 }
381
382 /** FIXME: below uevent functions usage and role are unclear, during refactoring
383    these can be removed.
384 */
385 static void esd_action(void)
386 {
387         const struct device_ops *touchscreen_ops = NULL;
388
389         _I("ESD on");
390
391         touchscreen_ops = find_device("touchscreen");
392
393         if (!check_default(touchscreen_ops))
394                 touchscreen_ops->stop(NORMAL_MODE);
395         display_panel_set_panel_state_by_off_state(NORMAL_MODE);
396         display_panel_set_panel_state_by_on_state(NORMAL_MODE);
397         if (!check_default(touchscreen_ops))
398                 touchscreen_ops->start(NORMAL_MODE);
399 }
400
401 static void lcd_uevent_changed(struct udev_device *dev)
402 {
403         const char *devpath;
404         const char *action;
405
406         devpath = udev_device_get_devpath(dev);
407         if (!devpath)
408                 return;
409
410         if (!fnmatch(LCD_ESD_PATH, devpath, 0)) {
411                 action = udev_device_get_action(dev);
412                 if (action && !strcmp(action, UDEV_CHANGE))
413                         esd_action();
414         }
415 }
416
417 static const struct uevent_handler lcd_uevent_ops = {
418         .subsystem      = LCD_EVENT_SUBSYSTEM,
419         .uevent_func    = lcd_uevent_changed,
420         .data           = NULL,
421 };
422
423 static gboolean handle_sighup(gpointer data)
424 {
425         int signo = (int)(intptr_t) data;
426         _I("received sig hub %d", signo);
427         pm_save_logdump();
428
429         return G_SOURCE_REMOVE;
430 }
431
432 static int delayed_init_done(void *data)
433 {
434         static bool done = false;
435
436         if (!data)
437                 return done;
438
439         done = *(int*)data;
440         if (!done)
441                 return done;
442
443         _I("Booting done, release booting lock.");
444         display_lock_request_unlock_with_option(DEVICED_EVENT_MISC_BOOTING, LCD_NORMAL, PM_SLEEP_MARGIN);
445         display_lock_request_unlock_with_option(DEVICED_EVENT_MISC_BOOTING, LCD_OFF, PM_SLEEP_MARGIN);
446
447         return done;
448 }
449
450 int display_is_lcdon_blocked(void)
451 {
452         if (silent_boot && !delayed_init_done(NULL))
453                 return LCDON_BLOCK_DURING_SILENT_BOOT;
454
455         return LCDON_BLOCK_NONE;
456 }
457
458 static void init_lcd_operation(void)
459 {
460         const struct device_ops *ops = NULL;
461
462         ops = find_device("display");
463         if (!check_default(ops))
464                 display_register_dependent_device(ops);
465
466         ops = find_device("touchkey");
467         if (!check_default(ops))
468                 display_register_dependent_device(ops);
469
470         ops = find_device("touchscreen");
471         if (!check_default(ops))
472                 display_register_dependent_device(ops);
473 }
474
475 static void load_display_hal_backend(void)
476 {
477         int ret;
478
479         if (g_display_hal_backend_available)
480                 return;
481
482         ret = hal_device_display_get_backend();
483         if (ret < 0) {
484                 _W("There is no HAL for display.");
485                 g_display_hal_backend_available = false;
486         }
487
488         g_display_hal_backend_available = true;
489         _W("Display device structure load success.");
490 }
491
492 static int unload_display_hal_backend(void)
493 {
494         g_display_hal_backend_available = false;
495         return hal_device_display_put_backend();
496 }
497
498 static int display_probe(void *data)
499 {
500         int ret = 0;
501
502         /**
503          * FIXME: As there is no counterpart of the display_probe(),
504          *  only syscommon_plugin_deviced_display_get_backend() is processed
505          *  and syscommon_plugin_deviced_display_put_backend() won't be called.
506          */
507         ret = syscommon_plugin_deviced_display_get_backend();
508         if (ret < 0) {
509                 /**
510                  * Legacy routine:
511                  *   Plugin probe()/init() by display_plugin_device_ops
512                  *   when there is no plugin backend.
513                  */
514                 display_plugin_device_ops = find_device("display-plugin");
515                 if (display_plugin_device_ops && display_plugin_device_ops->probe) {
516                         ret = display_plugin_device_ops->probe(&g_display_plugin);
517                         if (ret < 0)
518                                 return ret;
519                 }
520         }
521
522         for (int i = 0; i < SYSCOMMON_DEVICED_DISPLAY_STATE_END; ++i)
523                 if (!g_display_plugin.display_states[i])
524                         g_display_plugin.display_states[i] = &default_states[i];
525
526         if (!g_display_plugin.config) {
527                 ret = syscommon_plugin_deviced_display_load_config(&g_display_plugin.config);
528                 if (ret < 0)
529                         return ret;
530         }
531
532         /**
533          * load display hal backend
534          * if there is no display shared library,
535          * deviced does not provide any method and function of display.
536          */
537         load_display_hal_backend();
538         return 0;
539 }
540
541 static int input_init_handler(void)
542 {
543         if (!g_display_plugin.config->input_support)
544                 remove_device_by_devname("input");
545
546         return 0;
547 }
548
549 static void display_init(void *data)
550 {
551         bool timeout_enable = false;
552         int lcd_always_on = 0;
553         int timeout = 0;
554         int ret = 0;
555         unsigned int flags = (WITHOUT_STARTNOTI | FLAG_X_DPMS);
556         enum syscommon_deviced_display_state current;
557
558
559         g_unix_signal_add(SIGHUP, handle_sighup, (gpointer) SIGHUP);
560
561         if (display_plugin_device_ops && display_plugin_device_ops->init)
562                 display_plugin_device_ops->init(data);
563
564         display_plugin_config_load();
565
566         register_kernel_uevent_control(&lcd_uevent_ops);
567
568         syscommon_notifier_subscribe_notify(DEVICED_NOTIFIER_DELAYED_INIT, delayed_init_done);
569         syscommon_notifier_subscribe_notify(DEVICED_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
570         syscommon_notifier_subscribe_notify(DEVICED_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
571         syscommon_notifier_subscribe_notify(DEVICED_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
572         display_signal_register_display_brightness_notifier();
573         display_misc_register_battery_health_notifier();
574         syscommon_notifier_subscribe_notify(DEVICED_NOTIFIER_POWER_RESUME_FROM_ECHO_MEM, power_resume_from_echomem_callback);
575         syscommon_notifier_subscribe_notify(DEVICED_NOTIFIER_POWEROFF_TRIGGERED, poweroff_triggered_callback);
576
577         init_save_userlock();
578
579         ret = init_setting(NULL);
580         if (ret != 0)
581                 _W("Failed to init: setting init error");
582
583         display_plugin_config_get_timeout_enable(&timeout_enable);
584         if (timeout_enable)
585                 display_initialize_display_state_timeout_from_setting();
586
587         syscommon_notifier_subscribe_notify(DEVICED_NOTIFIER_VITAL_STATE, vital_state_changed);
588
589         _I("input init");
590         ret = input_init_handler();
591         pm_lock_detector_init();
592         if (ret != 0)
593                 _W("Failed to init: input devices poll init error");
594
595         _I("Dbus init.");
596         ret = init_pm_dbus();
597         if (ret != 0)
598                 _W("Failed to init: dbus initialization error");
599
600         display_ops_init(NULL);
601 #ifdef ENABLE_PM_LOG
602                 pm_history_init();
603 #endif
604         init_lcd_operation();
605         display_set_initial_brightness();
606         display_set_initial_battery_flag();
607         display_set_initial_lockscreen_status();
608
609         /* In smd test, TSP should be turned off if display panel is not existed. */
610         if (display_panel_get_dpms_cached_state() == -ENOENT) {
611                 _I("Display panel is not existed.");
612                 lcd_direct_control(SYSCOMMON_DEVICED_DPMS_OFF, NORMAL_MODE);
613                 display_unregister_dependent_device();
614         }
615
616         /* wm_ready needs to be checked
617                 * since display manager can be launched later than deviced.
618                 * In the case, display cannot be turned on at the first booting */
619         // wm_ready = check_wm_ready();
620         if (display_panel_init_dpms()) {
621                 if (display_is_lcdon_blocked() != LCDON_BLOCK_NONE) {
622                         display_panel_lcd_off_procedure(LCD_OFF_BY_EVENT);
623                 } else {
624                         display_panel_lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
625                 }
626         } else {
627                 display_add_timer_for_waiting_dpms_init();
628         }
629
630         display_plugin_config_get_lcd_always_on(&lcd_always_on);
631         if (lcd_always_on) {
632                 _I("LCD always on.");
633                 display_state_transition_set_transition_table_display_state(SYSCOMMON_DEVICED_DISPLAY_STATE_ON, SYSCOMMON_DEVICED_DISPLAY_STATE_ON, EVENT_TIMEOUT);
634         }
635
636         if (flags & WITHOUT_STARTNOTI) {        /* start without noti */
637                 _I("Start Power managing without noti");
638                 syscommon_resman_set_resource_attr_uint64_4(SYSCOMMON_RESOURCE_ID(DEVICED_RESOURCE_TYPE_POWER),
639                         DEVICED_POWER_ATTR_UINT64_4_CURRENT_STATE,
640                         DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL,
641                         HAL_DEVICE_POWER_TRANSITION_REASON_UNKNOWN, 0);
642
643                 /*
644                         * Lock lcd off until booting is done.
645                         * deviced guarantees all booting script is executing.
646                         * Last script of booting unlocks this suspend blocking state.
647                         */
648                 display_lock_request_lock_with_option(DEVICED_EVENT_MISC_BOOTING, LCD_OFF,
649                                         STAY_CUR_STATE, DELAYED_INIT_WATING_TIME);
650
651                 /* Initial display state right after the booting done */
652                 if (display_is_lcdon_blocked())
653                         set_pm_cur_state(SYSCOMMON_DEVICED_DISPLAY_STATE_OFF);
654                 else
655                         set_pm_cur_state(SYSCOMMON_DEVICED_DISPLAY_STATE_ON);
656
657                 ret = display_state_get_current(&current);
658                 if (ret == 0) {
659                         ret = vconf_set_int(VCONFKEY_PM_STATE, current);
660                         if (ret < 0)
661                                 _E("Failed to set vconf value for pm cur state: %d", vconf_get_ext_errno());
662                 }
663
664                 display_set_display_ops_status(DEVICE_OPS_STATUS_START);
665                 if (timeout_enable) {
666                         display_plugin_state_get_timeout(SYSCOMMON_DEVICED_DISPLAY_STATE_ON, &timeout);
667                         /* check minimun lcd on time */
668                         if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT)) {
669                                 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
670                         }
671                         display_lock_request_lock_with_option(DEVICED_EVENT_MISC_BOOTING, LCD_NORMAL,
672                                                 STAY_CUR_STATE, timeout);
673                 }
674         }
675
676         set_display_init_direction(g_display_plugin.config->display_init_direction);
677 }
678
679 static void display_exit(void *data)
680 {
681         const struct device_ops *ops = NULL;
682
683         if (display_plugin_device_ops && display_plugin_device_ops->exit)
684                 display_plugin_device_ops->exit(data);
685
686         display_set_display_ops_status(DEVICE_OPS_STATUS_STOP);
687
688         /* Set current state to SYSCOMMON_DEVICED_DISPLAY_STATE_ON */
689         set_pm_cur_state(SYSCOMMON_DEVICED_DISPLAY_STATE_ON);
690         set_setting_pmstate(SYSCOMMON_DEVICED_DISPLAY_STATE_ON);
691         /* timeout is not needed */
692         display_state_transition_reset_state_transition_timeout(TIMEOUT_NONE);
693
694         unregister_kernel_uevent_control(&lcd_uevent_ops);
695
696         display_ops_exit(NULL);
697
698         exit_setting();
699
700         display_backlight_update_by_default_brightness();
701
702         display_panel_exit_dpms();
703
704         ops = find_device("touchscreen");
705         if (!check_default(ops))
706                 ops->start(NORMAL_MODE);
707
708         ops = find_device("touchkey");
709         if (!check_default(ops))
710                 ops->start(NORMAL_MODE);
711
712         syscommon_notifier_unsubscribe_notify(DEVICED_NOTIFIER_VITAL_STATE, vital_state_changed);
713         syscommon_notifier_unsubscribe_notify(DEVICED_NOTIFIER_DELAYED_INIT, delayed_init_done);
714         syscommon_notifier_unsubscribe_notify(DEVICED_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
715         syscommon_notifier_unsubscribe_notify(DEVICED_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
716         syscommon_notifier_unsubscribe_notify(DEVICED_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
717         display_misc_unregister_battery_health_notifier();
718         display_signal_unregister_display_brightness_notifier();
719         syscommon_notifier_unsubscribe_notify(DEVICED_NOTIFIER_POWER_RESUME_FROM_ECHO_MEM, power_resume_from_echomem_callback);
720         syscommon_notifier_unsubscribe_notify(DEVICED_NOTIFIER_POWEROFF_TRIGGERED, poweroff_triggered_callback);
721
722         display_unregister_dependent_device();
723         free_lock_info_list();
724
725         unload_display_hal_backend();
726 }
727
728 static int display_start(enum device_flags flags)
729 {
730         /* NORMAL MODE */
731         if (flags & NORMAL_MODE) {
732                 if (flags & LCD_PANEL_OFF_MODE)
733                         /* standby on */
734                         display_panel_set_panel_state_by_standby_state(true);
735                 else
736                         /* normal lcd on */
737                         display_panel_set_panel_state_by_on_state(flags);
738                 return 0;
739         }
740
741         /* CORE LOGIC MODE */
742         if (!(flags & CORE_LOGIC_MODE))
743                 return 0;
744
745         if (display_ops_status == DEVICE_OPS_STATUS_START)
746                 return -EALREADY;
747
748         if (display_probe(NULL) < 0)
749                 return -EPERM;
750
751         display_init(NULL);
752
753         return 0;
754 }
755
756 static int display_stop(enum device_flags flags)
757 {
758         /* NORMAL MODE */
759         if (flags & NORMAL_MODE || flags & FORCE_OFF_MODE) {
760                 display_panel_set_panel_state_by_off_state(flags);
761                 return 0;
762         }
763
764         /* CORE LOGIC MODE */
765         if (!(flags & CORE_LOGIC_MODE))
766                 return 0;
767
768         if (display_ops_status == DEVICE_OPS_STATUS_STOP)
769                 return -EALREADY;
770
771         display_exit(NULL);
772
773         return 0;
774 }
775
776 static int display_status(void)
777 {
778         return display_ops_status;
779 }
780
781 static const struct device_ops display_device_ops = {
782         .priority = DEVICE_PRIORITY_HIGH,
783         DECLARE_NAME_LEN("display"),
784         .probe    = display_probe,
785         .init     = display_init,
786         .exit     = display_exit,
787         .start    = display_start,
788         .stop     = display_stop,
789         .status   = display_status,
790 };
791
792 DEVICE_OPS_REGISTER(&display_device_ops)