From b12f0ae9e8dfee55c7757f9c4be3b1154c366754 Mon Sep 17 00:00:00 2001
From: Ben Skeggs <bskeggs@redhat.com>
Date: Sun, 10 Aug 2014 04:10:19 +1000
Subject: [PATCH] drm/nouveau: store vblank event handler data in nv_crtc

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
---
 drivers/gpu/drm/nouveau/nouveau_crtc.h    |  1 +
 drivers/gpu/drm/nouveau/nouveau_display.c | 55 ++++++++++++-----------
 drivers/gpu/drm/nouveau/nouveau_display.h |  2 -
 3 files changed, 29 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_crtc.h b/drivers/gpu/drm/nouveau/nouveau_crtc.h
index a7cbbe9d5d8d..6af9b58821c0 100644
--- a/drivers/gpu/drm/nouveau/nouveau_crtc.h
+++ b/drivers/gpu/drm/nouveau/nouveau_crtc.h
@@ -31,6 +31,7 @@ struct nouveau_crtc {
 	struct drm_crtc base;
 
 	int index;
+	struct nouveau_eventh *vblank;
 
 	uint32_t dpms_saved_fp_control;
 	uint32_t fp_users;
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index b6e258faa4f7..a1247f258240 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -44,28 +44,36 @@
 static int
 nouveau_display_vblank_handler(void *data, u32 type, int head)
 {
-	struct nouveau_drm *drm = data;
-	drm_handle_vblank(drm->dev, head);
+	struct nouveau_crtc *nv_crtc = data;
+	drm_handle_vblank(nv_crtc->base.dev, nv_crtc->index);
 	return NVKM_EVENT_KEEP;
 }
 
 int
 nouveau_display_vblank_enable(struct drm_device *dev, int head)
 {
-	struct nouveau_display *disp = nouveau_display(dev);
-	if (disp) {
-		nouveau_event_get(disp->vblank[head]);
-		return 0;
+	struct drm_crtc *crtc;
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+		if (nv_crtc->index == head) {
+			nouveau_event_get(nv_crtc->vblank);
+			return 0;
+		}
 	}
-	return -EIO;
+	return -EINVAL;
 }
 
 void
 nouveau_display_vblank_disable(struct drm_device *dev, int head)
 {
-	struct nouveau_display *disp = nouveau_display(dev);
-	if (disp)
-		nouveau_event_put(disp->vblank[head]);
+	struct drm_crtc *crtc;
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+		if (nv_crtc->index == head) {
+			nouveau_event_put(nv_crtc->vblank);
+			return;
+		}
+	}
 }
 
 static inline int
@@ -151,36 +159,29 @@ nouveau_display_vblstamp(struct drm_device *dev, int head, int *max_error,
 static void
 nouveau_display_vblank_fini(struct drm_device *dev)
 {
-	struct nouveau_display *disp = nouveau_display(dev);
-	int i;
+	struct drm_crtc *crtc;
 
 	drm_vblank_cleanup(dev);
 
-	if (disp->vblank) {
-		for (i = 0; i < dev->mode_config.num_crtc; i++)
-			nouveau_event_ref(NULL, &disp->vblank[i]);
-		kfree(disp->vblank);
-		disp->vblank = NULL;
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+		nouveau_event_ref(NULL, &nv_crtc->vblank);
 	}
 }
 
 static int
 nouveau_display_vblank_init(struct drm_device *dev)
 {
-	struct nouveau_display *disp = nouveau_display(dev);
 	struct nouveau_drm *drm = nouveau_drm(dev);
 	struct nouveau_disp *pdisp = nouveau_disp(drm->device);
-	int ret, i;
-
-	disp->vblank = kzalloc(dev->mode_config.num_crtc *
-			       sizeof(*disp->vblank), GFP_KERNEL);
-	if (!disp->vblank)
-		return -ENOMEM;
+	struct drm_crtc *crtc;
+	int ret;
 
-	for (i = 0; i < dev->mode_config.num_crtc; i++) {
-		ret = nouveau_event_new(pdisp->vblank, 1, i,
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+		ret = nouveau_event_new(pdisp->vblank, 1, nv_crtc->index,
 					nouveau_display_vblank_handler,
-					drm, &disp->vblank[i]);
+					nv_crtc, &nv_crtc->vblank);
 		if (ret) {
 			nouveau_display_vblank_fini(dev);
 			return ret;
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h
index a21fd2dbeb18..37bf0d224a4c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.h
+++ b/drivers/gpu/drm/nouveau/nouveau_display.h
@@ -40,8 +40,6 @@ struct nouveau_display {
 	void (*fb_dtor)(struct drm_framebuffer *);
 
 	struct nouveau_object *core;
-	struct nouveau_eventh **vblank;
-
 
 	struct drm_property *dithering_mode;
 	struct drm_property *dithering_depth;
-- 
GitLab