int display_hibernation_power_off(struct display_driver *dispdrv)
{
	int ret = 0;
	struct s3c_fb *sfb = dispdrv->decon_driver.sfb;

	disp_pm_gate_lock(dispdrv, true);
	mutex_lock(&dispdrv->pm_status.pm_lock);
	if (sfb->power_state == POWER_DOWN) {
		pr_info("%s, DECON are already power off state\n", __func__);
		goto done;
	}

	if (atomic_read(&dispdrv->pm_status.lock_count) > GATE_LOCK_CNT) {
		pr_info("%s, DECON does not need power-off\n", __func__);
		goto done;
	}
	if (get_display_line_count(dispdrv)) {
		pm_debug("wait until last frame is totally transferred %d:",
				get_display_line_count(dispdrv));
		goto done;
	}

	pm_info("##### +");
	sfb->power_state = POWER_HIBER_DOWN;
	__display_hibernation_power_off(dispdrv);
	disp_pm_runtime_put_sync(dispdrv);

	request_dynamic_hotplug(true);
	pm_info("##### -\n");
done:
	mutex_unlock(&dispdrv->pm_status.pm_lock);
	disp_pm_gate_lock(dispdrv, false);

	return ret;
}
int display_hibernation_power_on(struct display_driver *dispdrv)
{
	int ret = 0;
	struct s3c_fb *sfb = dispdrv->decon_driver.sfb;

	pm_info("##### +");
	disp_pm_gate_lock(dispdrv, true);
	mutex_lock(&dispdrv->pm_status.pm_lock);
	if (sfb->power_state == POWER_ON) {
		pr_info("%s, DECON are already power on state\n", __func__);
		goto done;
	}

	request_dynamic_hotplug(false);

	pm_runtime_get_sync(dispdrv->display_driver);
	__display_hibernation_power_on(dispdrv);
	sfb->power_state = POWER_ON;

done:
	mutex_unlock(&dispdrv->pm_status.pm_lock);
	disp_pm_gate_lock(dispdrv, false);
	pm_info("##### -\n");
	return ret;
}
void debug_function(struct display_driver *dispdrv, const char *buf)
{
#ifndef CONFIG_FB_HIBERNATION_DISPLAY
	pm_info("%s: does not support", __func__);
	return;
#endif
	pm_info("calls [%s] to control gating function\n", buf);
	if (!strcmp(buf, "clk-gate-on")) {
		dispdrv->pm_status.clock_gating_on = true;
	} else if (!strcmp(buf, "clk-gate-off")) {
		dispdrv->pm_status.clock_gating_on = false;
	} else if (!strcmp(buf, "pwr-gate-on")) {
		dispdrv->pm_status.power_gating_on = true;
	} else if (!strcmp(buf, "pwr-gate-off")) {
		dispdrv->pm_status.power_gating_on = false;
	} else if (!strcmp(buf, "hotplug-gate-on")) {
		dispdrv->pm_status.hotplug_gating_on = true;
	} else if (!strcmp(buf, "hotplug-gate-off")) {
		dispdrv->pm_status.hotplug_gating_on = false;
	} else {
		pr_err("INVALID parameter: '%s'\n", buf);
	}
	pm_info("CLOCK GATING MODE: %s\n",
		dispdrv->pm_status.clock_gating_on == true? "TRUE":"FALSE");
	pm_info("POWER GATING MODE: %s\n",
		dispdrv->pm_status.power_gating_on == true? "TRUE":"FALSE");
	pm_info("HOTPLUG GATING MODE: %s\n",
		dispdrv->pm_status.hotplug_gating_on == true? "TRUE":"FALSE");
}
void debug_function(struct display_driver *dispdrv, const char *buf)
{
	long input_time;
#ifndef CONFIG_FB_HIBERNATION_DISPLAY
	pm_info("%s: does not support", __func__);
	return;
#endif
	pm_info("calls [%s] to control gating function\n", buf);

	if (!kstrtol(buf, 10, &input_time)) {
		if (input_time == 0) {
			request_dynamic_hotplug(false);
			dispdrv->pm_status.hotplug_gating_on = false;
		} else {
			dispdrv->pm_status.hotplug_delay_msec = input_time;
			dispdrv->pm_status.hotplug_gating_on = true;
			if (dispdrv->decon_driver.sfb->power_state == POWER_HIBER_DOWN) {
				request_dynamic_hotplug(true);
			}
		}
		pm_info("Hotplug delay time is : %ld ms\n", input_time);
		pm_info("HOTPLUG GATING MODE: %s\n",
				dispdrv->pm_status.hotplug_gating_on == true? "TRUE":"FALSE");
		return;
	}
	if (!strcmp(buf, "clk-gate-on")) {
		dispdrv->pm_status.clock_gating_on = true;
	} else if (!strcmp(buf, "clk-gate-off")) {
		dispdrv->pm_status.clock_gating_on = false;
	} else if (!strcmp(buf, "pwr-gate-on")) {
		dispdrv->pm_status.power_gating_on = true;
	} else if (!strcmp(buf, "pwr-gate-off")) {
		dispdrv->pm_status.power_gating_on = false;
	} else if (!strcmp(buf, "hotplug-gate-on")) {
		dispdrv->pm_status.hotplug_gating_on = true;
	} else if (!strcmp(buf, "hotplug-gate-off")) {
		request_dynamic_hotplug(false);
		dispdrv->pm_status.hotplug_gating_on = false;
	} else {
		pr_err("INVALID parameter: '%s'\n", buf);
	}
	pm_info("CLOCK GATING MODE: %s\n",
		dispdrv->pm_status.clock_gating_on == true? "TRUE":"FALSE");
	pm_info("POWER GATING MODE: %s\n",
		dispdrv->pm_status.power_gating_on == true? "TRUE":"FALSE");
	pm_info("HOTPLUG GATING MODE: %s\n",
		dispdrv->pm_status.hotplug_gating_on == true? "TRUE":"FALSE");
}
void display_block_clock_on(struct display_driver *dispdrv)
{
	if (!get_display_power_status()) {
		pm_info("Requested a pm_runtime_get_sync, but power still off");
		pm_runtime_get_sync(dispdrv->display_driver);
		if (!get_display_power_status())
			BUG();
	}

	mutex_lock(&dispdrv->pm_status.clk_lock);
	if (!dispdrv->pm_status.clock_enabled) {
		pm_debug("+");
		__display_block_clock_on(dispdrv);
		dispdrv->pm_status.clock_enabled = 1;
		pm_debug("-");
	}
	mutex_unlock(&dispdrv->pm_status.clk_lock);
}