drm/nouveau/disp: introduce proper init/fini, separate from create/destroy

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index 38623a2..803248d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -262,7 +262,10 @@
 	if (ret)
 		return ret;
 
-	return 0;
+	ret = disp->init(dev);
+	if (ret)
+		disp->destroy(dev);
+	return ret;
 }
 
 void
@@ -271,6 +274,7 @@
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct nouveau_display_engine *disp = &dev_priv->engine.display;
 
+	disp->fini(dev);
 	disp->destroy(dev);
 	drm_mode_config_cleanup(dev);
 }
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index dc88248..a22ca47 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -396,8 +396,9 @@
 	int (*early_init)(struct drm_device *);
 	void (*late_takedown)(struct drm_device *);
 	int (*create)(struct drm_device *);
-	int (*init)(struct drm_device *);
 	void (*destroy)(struct drm_device *);
+	int (*init)(struct drm_device *);
+	void (*fini)(struct drm_device *);
 
 	struct drm_property *dithering_mode;
 	struct drm_property *dithering_depth;
@@ -1343,13 +1344,15 @@
 extern int nv04_display_early_init(struct drm_device *);
 extern void nv04_display_late_takedown(struct drm_device *);
 extern int nv04_display_create(struct drm_device *);
-extern int nv04_display_init(struct drm_device *);
 extern void nv04_display_destroy(struct drm_device *);
+extern int nv04_display_init(struct drm_device *);
+extern void nv04_display_fini(struct drm_device *);
 
 /* nvd0_display.c */
 extern int nvd0_display_create(struct drm_device *);
-extern int nvd0_display_init(struct drm_device *);
 extern void nvd0_display_destroy(struct drm_device *);
+extern int nvd0_display_init(struct drm_device *);
+extern void nvd0_display_fini(struct drm_device *);
 
 /* nv04_crtc.c */
 extern int nv04_crtc_create(struct drm_device *, int index);
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index 46831fe..0c3368b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -80,8 +80,9 @@
 		engine->display.early_init	= nv04_display_early_init;
 		engine->display.late_takedown	= nv04_display_late_takedown;
 		engine->display.create		= nv04_display_create;
-		engine->display.init		= nv04_display_init;
 		engine->display.destroy		= nv04_display_destroy;
+		engine->display.init		= nv04_display_init;
+		engine->display.fini		= nv04_display_fini;
 		engine->gpio.init		= nouveau_stub_init;
 		engine->gpio.takedown		= nouveau_stub_takedown;
 		engine->gpio.get		= NULL;
@@ -129,8 +130,9 @@
 		engine->display.early_init	= nv04_display_early_init;
 		engine->display.late_takedown	= nv04_display_late_takedown;
 		engine->display.create		= nv04_display_create;
-		engine->display.init		= nv04_display_init;
 		engine->display.destroy		= nv04_display_destroy;
+		engine->display.init		= nv04_display_init;
+		engine->display.fini		= nv04_display_fini;
 		engine->gpio.init		= nouveau_stub_init;
 		engine->gpio.takedown		= nouveau_stub_takedown;
 		engine->gpio.get		= nv10_gpio_get;
@@ -178,8 +180,9 @@
 		engine->display.early_init	= nv04_display_early_init;
 		engine->display.late_takedown	= nv04_display_late_takedown;
 		engine->display.create		= nv04_display_create;
-		engine->display.init		= nv04_display_init;
 		engine->display.destroy		= nv04_display_destroy;
+		engine->display.init		= nv04_display_init;
+		engine->display.fini		= nv04_display_fini;
 		engine->gpio.init		= nouveau_stub_init;
 		engine->gpio.takedown		= nouveau_stub_takedown;
 		engine->gpio.get		= nv10_gpio_get;
@@ -227,8 +230,9 @@
 		engine->display.early_init	= nv04_display_early_init;
 		engine->display.late_takedown	= nv04_display_late_takedown;
 		engine->display.create		= nv04_display_create;
-		engine->display.init		= nv04_display_init;
 		engine->display.destroy		= nv04_display_destroy;
+		engine->display.init		= nv04_display_init;
+		engine->display.fini		= nv04_display_fini;
 		engine->gpio.init		= nouveau_stub_init;
 		engine->gpio.takedown		= nouveau_stub_takedown;
 		engine->gpio.get		= nv10_gpio_get;
@@ -279,8 +283,9 @@
 		engine->display.early_init	= nv04_display_early_init;
 		engine->display.late_takedown	= nv04_display_late_takedown;
 		engine->display.create		= nv04_display_create;
-		engine->display.init		= nv04_display_init;
 		engine->display.destroy		= nv04_display_destroy;
+		engine->display.init		= nv04_display_init;
+		engine->display.fini		= nv04_display_fini;
 		engine->gpio.init		= nouveau_stub_init;
 		engine->gpio.takedown		= nouveau_stub_takedown;
 		engine->gpio.get		= nv10_gpio_get;
@@ -336,8 +341,9 @@
 		engine->display.early_init	= nv50_display_early_init;
 		engine->display.late_takedown	= nv50_display_late_takedown;
 		engine->display.create		= nv50_display_create;
-		engine->display.init		= nv50_display_init;
 		engine->display.destroy		= nv50_display_destroy;
+		engine->display.init		= nv50_display_init;
+		engine->display.fini		= nv50_display_fini;
 		engine->gpio.init		= nv50_gpio_init;
 		engine->gpio.takedown		= nv50_gpio_fini;
 		engine->gpio.get		= nv50_gpio_get;
@@ -411,8 +417,9 @@
 		engine->display.early_init	= nv50_display_early_init;
 		engine->display.late_takedown	= nv50_display_late_takedown;
 		engine->display.create		= nv50_display_create;
-		engine->display.init		= nv50_display_init;
 		engine->display.destroy		= nv50_display_destroy;
+		engine->display.init		= nv50_display_init;
+		engine->display.fini		= nv50_display_fini;
 		engine->gpio.init		= nv50_gpio_init;
 		engine->gpio.takedown		= nouveau_stub_takedown;
 		engine->gpio.get		= nv50_gpio_get;
@@ -463,8 +470,9 @@
 		engine->display.early_init	= nouveau_stub_init;
 		engine->display.late_takedown	= nouveau_stub_takedown;
 		engine->display.create		= nvd0_display_create;
-		engine->display.init		= nvd0_display_init;
 		engine->display.destroy		= nvd0_display_destroy;
+		engine->display.init		= nvd0_display_init;
+		engine->display.fini		= nvd0_display_fini;
 		engine->gpio.init		= nv50_gpio_init;
 		engine->gpio.takedown		= nouveau_stub_takedown;
 		engine->gpio.get		= nvd0_gpio_get;
diff --git a/drivers/gpu/drm/nouveau/nv04_display.c b/drivers/gpu/drm/nouveau/nv04_display.c
index 6bd8518..7047d37 100644
--- a/drivers/gpu/drm/nouveau/nv04_display.c
+++ b/drivers/gpu/drm/nouveau/nv04_display.c
@@ -243,6 +243,11 @@
 	return 0;
 }
 
+void
+nv04_display_fini(struct drm_device *dev)
+{
+}
+
 static void
 nv04_vblank_crtc0_isr(struct drm_device *dev)
 {
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index a59d0b9..7a57c30 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -264,7 +264,8 @@
 	return nv50_display_sync(dev);
 }
 
-static int nv50_display_disable(struct drm_device *dev)
+void
+nv50_display_fini(struct drm_device *dev)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct nv50_display *disp = nv50_display(dev);
@@ -337,16 +338,16 @@
 		nv_wr32(dev, 0xe074, 0xffffffff);
 		nv_wr32(dev, 0xe070, 0x00000000);
 	}
-	return 0;
 }
 
-int nv50_display_create(struct drm_device *dev)
+int
+nv50_display_create(struct drm_device *dev)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct dcb_table *dcb = &dev_priv->vbios.dcb;
 	struct drm_connector *connector, *ct;
 	struct nv50_display *priv;
-	int ret, i;
+	int i;
 
 	NV_DEBUG_KMS(dev, "\n");
 
@@ -399,13 +400,6 @@
 
 	tasklet_init(&priv->tasklet, nv50_display_bh, (unsigned long)dev);
 	nouveau_irq_register(dev, 26, nv50_display_isr);
-
-	ret = nv50_display_init(dev);
-	if (ret) {
-		nv50_display_destroy(dev);
-		return ret;
-	}
-
 	return 0;
 }
 
@@ -416,7 +410,6 @@
 
 	NV_DEBUG_KMS(dev, "\n");
 
-	nv50_display_disable(dev);
 	nouveau_irq_unregister(dev, 26);
 	kfree(disp);
 }
diff --git a/drivers/gpu/drm/nouveau/nv50_display.h b/drivers/gpu/drm/nouveau/nv50_display.h
index 0cd8819..11e2f1e 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.h
+++ b/drivers/gpu/drm/nouveau/nv50_display.h
@@ -69,6 +69,7 @@
 void nv50_display_late_takedown(struct drm_device *dev);
 int nv50_display_create(struct drm_device *dev);
 int nv50_display_init(struct drm_device *dev);
+void nv50_display_fini(struct drm_device *dev);
 void nv50_display_destroy(struct drm_device *dev);
 int nv50_crtc_blank(struct nouveau_crtc *, bool blank);
 int nv50_crtc_set_clock(struct drm_device *, int head, int pclk);
diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c
index 75f9958..614c652 100644
--- a/drivers/gpu/drm/nouveau/nvd0_display.c
+++ b/drivers/gpu/drm/nouveau/nvd0_display.c
@@ -1341,7 +1341,7 @@
 /******************************************************************************
  * Init
  *****************************************************************************/
-static void
+void
 nvd0_display_fini(struct drm_device *dev)
 {
 	int i;
@@ -1461,8 +1461,6 @@
 	struct nvd0_display *disp = nvd0_display(dev);
 	struct pci_dev *pdev = dev->pdev;
 
-	nvd0_display_fini(dev);
-
 	pci_free_consistent(pdev, PAGE_SIZE, disp->evo[0].ptr, disp->evo[0].handle);
 	nouveau_gpuobj_ref(NULL, &disp->mem);
 	nouveau_irq_unregister(dev, 26);
@@ -1588,10 +1586,6 @@
 		goto out;
 	}
 
-	ret = nvd0_display_init(dev);
-	if (ret)
-		goto out;
-
 out:
 	if (ret)
 		nvd0_display_destroy(dev);