static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
                                     struct drm_framebuffer *fb,
                                     struct drm_pending_vblank_event *event)
{
    struct drm_device *dev = crtc->dev;
    struct exynos_drm_private *dev_priv = dev->dev_private;
    struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
    struct drm_framebuffer *old_fb = crtc->fb;
    int ret = -EINVAL;

    DRM_DEBUG_KMS("%s\n", __FILE__);

    mutex_lock(&dev->struct_mutex);

    if (event) {
        /*
         * the pipe from user always is 0 so we can set pipe number
         * of current owner to event.
         */
        event->pipe = exynos_crtc->pipe;

        ret = drm_vblank_get(dev, exynos_crtc->pipe);
        if (ret) {
            DRM_DEBUG("failed to acquire vblank counter\n");
            list_del(&event->base.link);

            goto out;
        }

        list_add_tail(&event->base.link,
                      &dev_priv->pageflip_event_list);

        crtc->fb = fb;
        ret = exynos_drm_crtc_update(crtc);
        if (ret) {
            crtc->fb = old_fb;
            drm_vblank_put(dev, exynos_crtc->pipe);
            list_del(&event->base.link);

            goto out;
        }

        /*
         * the values related to a buffer of the drm framebuffer
         * to be applied should be set at here. because these values
         * first, are set to shadow registers and then to
         * real registers at vsync front porch period.
         */
        exynos_drm_crtc_apply(crtc);
    }
out:
    mutex_unlock(&dev->struct_mutex);
    return ret;
}
static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
				      struct drm_framebuffer *fb,
				      struct drm_pending_vblank_event *event)
{
	struct drm_device *dev = crtc->dev;
	struct exynos_drm_private *dev_priv = dev->dev_private;
	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
	struct drm_framebuffer *old_fb = crtc->fb;
	int ret = -EINVAL;

	DRM_DEBUG_KMS("%s\n", __FILE__);

	mutex_lock(&dev->struct_mutex);

	if (event) {
		/*
                                                             
                               
   */
		event->pipe = exynos_crtc->pipe;

		ret = drm_vblank_get(dev, exynos_crtc->pipe);
		if (ret) {
			DRM_DEBUG("failed to acquire vblank counter\n");
			list_del(&event->base.link);

			goto out;
		}

		list_add_tail(&event->base.link,
				&dev_priv->pageflip_event_list);

		crtc->fb = fb;
		ret = exynos_drm_crtc_update(crtc);
		if (ret) {
			crtc->fb = old_fb;
			drm_vblank_put(dev, exynos_crtc->pipe);
			list_del(&event->base.link);

			goto out;
		}

		/*
                                                          
                                                              
                                                   
                                                
   */
		exynos_drm_crtc_apply(crtc);
	}
out:
	mutex_unlock(&dev->struct_mutex);
	return ret;
}
static int exynos_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
        struct drm_framebuffer *old_fb)
{
    int ret;

    DRM_DEBUG_KMS("%s\n", __FILE__);

    ret = exynos_drm_crtc_update(crtc);
    if (ret)
        return ret;

    exynos_drm_crtc_apply(crtc);

    return ret;
}