diff --git a/drivers/gpu/drm/sti/Kconfig b/drivers/gpu/drm/sti/Kconfig
index fbccc105819b707c2b3be9383dfd1898cee239af..10c1b1926e6f9665b083df291632924d91c12ef5 100644
--- a/drivers/gpu/drm/sti/Kconfig
+++ b/drivers/gpu/drm/sti/Kconfig
@@ -6,12 +6,6 @@ config DRM_STI
 	select DRM_GEM_CMA_HELPER
 	select DRM_KMS_CMA_HELPER
 	select DRM_PANEL
-	select FW_LOADER_USER_HELPER_FALLBACK
+	select FW_LOADER
 	help
 	  Choose this option to enable DRM on STM stiH41x chipset
-
-config DRM_STI_FBDEV
-	bool "DRM frame buffer device for STMicroelectronics SoC stiH41x Serie"
-	depends on DRM_STI
-	help
-	  Choose this option to enable FBDEV on top of DRM for STM stiH41x chipset
diff --git a/drivers/gpu/drm/sti/Makefile b/drivers/gpu/drm/sti/Makefile
index e27490b492a5280a254b9a196d452f429abb9466..b8057620b3b35702f23476584c15efc0d2a7763e 100644
--- a/drivers/gpu/drm/sti/Makefile
+++ b/drivers/gpu/drm/sti/Makefile
@@ -1,26 +1,23 @@
-sticompositor-y := \
+sti-drm-y := \
 	sti_mixer.o \
 	sti_gdp.o \
 	sti_vid.o \
 	sti_cursor.o \
 	sti_compositor.o \
 	sti_crtc.o \
-	sti_plane.o
-
-stihdmi-y := sti_hdmi.o \
+	sti_plane.o \
+	sti_crtc.o \
+	sti_plane.o \
+	sti_hdmi.o \
 	sti_hdmi_tx3g0c55phy.o \
 	sti_hdmi_tx3g4c28phy.o \
-
-stidvo-y := sti_dvo.o \
-	sti_awg_utils.o
-
-obj-$(CONFIG_DRM_STI) = \
+	sti_dvo.o \
+	sti_awg_utils.o \
 	sti_vtg.o \
 	sti_vtac.o \
-	stihdmi.o \
 	sti_hda.o \
 	sti_tvout.o \
-	sticompositor.o \
 	sti_hqvdp.o \
-	stidvo.o \
 	sti_drv.o
+
+obj-$(CONFIG_DRM_STI) = sti-drm.o
diff --git a/drivers/gpu/drm/sti/sti_awg_utils.c b/drivers/gpu/drm/sti/sti_awg_utils.c
index 6029a2e3db1dc8feb5243e992abef98594d2a766..00d0698be9d33e7b4517c9e39c186607676a8399 100644
--- a/drivers/gpu/drm/sti/sti_awg_utils.c
+++ b/drivers/gpu/drm/sti/sti_awg_utils.c
@@ -65,7 +65,6 @@ static int awg_generate_instr(enum opcode opcode,
 
 			mux = 0;
 			data_enable = 0;
-			arg = (arg << 22) >> 22;
 			arg &= (0x3ff);
 			break;
 		case REPEAT:
@@ -77,14 +76,12 @@ static int awg_generate_instr(enum opcode opcode,
 
 			mux = 0;
 			data_enable = 0;
-			arg = (arg << 22) >> 22;
 			arg &= (0x3ff);
 			break;
 		case JUMP:
 			mux = 0;
 			data_enable = 0;
 			arg |= 0x40; /* for jump instruction 7th bit is 1 */
-			arg = (arg << 22) >> 22;
 			arg &= 0x3ff;
 			break;
 		case STOP:
@@ -94,7 +91,6 @@ static int awg_generate_instr(enum opcode opcode,
 		case RPTSET:
 		case RPLSET:
 		case HOLD:
-			arg = (arg << 24) >> 24;
 			arg &= (0x0ff);
 			break;
 		default:
diff --git a/drivers/gpu/drm/sti/sti_compositor.c b/drivers/gpu/drm/sti/sti_compositor.c
index c652627b1bcadbe05a1a759677724f7be8819c0a..afed2171beb9a4ce4e2a6031eb139fe0247b1ae0 100644
--- a/drivers/gpu/drm/sti/sti_compositor.c
+++ b/drivers/gpu/drm/sti/sti_compositor.c
@@ -263,7 +263,7 @@ static int sti_compositor_remove(struct platform_device *pdev)
 	return 0;
 }
 
-static struct platform_driver sti_compositor_driver = {
+struct platform_driver sti_compositor_driver = {
 	.driver = {
 		.name = "sti-compositor",
 		.of_match_table = compositor_of_match,
@@ -272,8 +272,6 @@ static struct platform_driver sti_compositor_driver = {
 	.remove = sti_compositor_remove,
 };
 
-module_platform_driver(sti_compositor_driver);
-
 MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
 MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/sti/sti_crtc.c b/drivers/gpu/drm/sti/sti_crtc.c
index 493c4a3006adb4b62e7074aff5f68f80dc7463c3..3ae09dcd4fd86c65fad95b13fc60aa596a1271e4 100644
--- a/drivers/gpu/drm/sti/sti_crtc.c
+++ b/drivers/gpu/drm/sti/sti_crtc.c
@@ -226,7 +226,7 @@ static void sti_crtc_atomic_flush(struct drm_crtc *crtc,
 	}
 }
 
-static struct drm_crtc_helper_funcs sti_crtc_helper_funcs = {
+static const struct drm_crtc_helper_funcs sti_crtc_helper_funcs = {
 	.enable = sti_crtc_enable,
 	.disable = sti_crtc_disabling,
 	.mode_fixup = sti_crtc_mode_fixup,
@@ -254,15 +254,17 @@ static int sti_crtc_set_property(struct drm_crtc *crtc,
 int sti_crtc_vblank_cb(struct notifier_block *nb,
 		       unsigned long event, void *data)
 {
-	struct drm_device *drm_dev;
 	struct sti_compositor *compo =
 		container_of(nb, struct sti_compositor, vtg_vblank_nb);
-	int *crtc = data;
+	struct drm_crtc *crtc = data;
+	struct sti_mixer *mixer;
 	unsigned long flags;
 	struct sti_private *priv;
+	unsigned int pipe;
 
-	drm_dev = compo->mixer[*crtc]->drm_crtc.dev;
-	priv = drm_dev->dev_private;
+	priv = crtc->dev->dev_private;
+	pipe = drm_crtc_index(crtc);
+	mixer = compo->mixer[pipe];
 
 	if ((event != VTG_TOP_FIELD_EVENT) &&
 	    (event != VTG_BOTTOM_FIELD_EVENT)) {
@@ -270,30 +272,30 @@ int sti_crtc_vblank_cb(struct notifier_block *nb,
 		return -EINVAL;
 	}
 
-	drm_handle_vblank(drm_dev, *crtc);
+	drm_crtc_handle_vblank(crtc);
 
-	spin_lock_irqsave(&drm_dev->event_lock, flags);
-	if (compo->mixer[*crtc]->pending_event) {
-		drm_send_vblank_event(drm_dev, -1,
-				      compo->mixer[*crtc]->pending_event);
-		drm_vblank_put(drm_dev, *crtc);
-		compo->mixer[*crtc]->pending_event = NULL;
+	spin_lock_irqsave(&crtc->dev->event_lock, flags);
+	if (mixer->pending_event) {
+		drm_crtc_send_vblank_event(crtc, mixer->pending_event);
+		drm_crtc_vblank_put(crtc);
+		mixer->pending_event = NULL;
 	}
-	spin_unlock_irqrestore(&drm_dev->event_lock, flags);
+	spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
 
-	if (compo->mixer[*crtc]->status == STI_MIXER_DISABLING) {
+	if (mixer->status == STI_MIXER_DISABLING) {
 		struct drm_plane *p;
 
 		/* Disable mixer only if all overlay planes (GDP and VDP)
 		 * are disabled */
-		list_for_each_entry(p, &drm_dev->mode_config.plane_list, head) {
+		list_for_each_entry(p, &crtc->dev->mode_config.plane_list,
+				    head) {
 			struct sti_plane *plane = to_sti_plane(p);
 
 			if ((plane->desc & STI_PLANE_TYPE_MASK) <= STI_VDP)
 				if (plane->status != STI_PLANE_DISABLED)
 					return 0;
 		}
-		sti_crtc_disable(&compo->mixer[*crtc]->drm_crtc);
+		sti_crtc_disable(crtc);
 	}
 
 	return 0;
@@ -304,25 +306,26 @@ int sti_crtc_enable_vblank(struct drm_device *dev, unsigned int pipe)
 	struct sti_private *dev_priv = dev->dev_private;
 	struct sti_compositor *compo = dev_priv->compo;
 	struct notifier_block *vtg_vblank_nb = &compo->vtg_vblank_nb;
+	struct drm_crtc *crtc = &compo->mixer[pipe]->drm_crtc;
 
 	DRM_DEBUG_DRIVER("\n");
 
 	if (sti_vtg_register_client(pipe == STI_MIXER_MAIN ?
 			compo->vtg_main : compo->vtg_aux,
-			vtg_vblank_nb, pipe)) {
+			vtg_vblank_nb, crtc)) {
 		DRM_ERROR("Cannot register VTG notifier\n");
 		return -EINVAL;
 	}
 
 	return 0;
 }
-EXPORT_SYMBOL(sti_crtc_enable_vblank);
 
 void sti_crtc_disable_vblank(struct drm_device *drm_dev, unsigned int pipe)
 {
 	struct sti_private *priv = drm_dev->dev_private;
 	struct sti_compositor *compo = priv->compo;
 	struct notifier_block *vtg_vblank_nb = &compo->vtg_vblank_nb;
+	struct drm_crtc *crtc = &compo->mixer[pipe]->drm_crtc;
 
 	DRM_DEBUG_DRIVER("\n");
 
@@ -332,13 +335,12 @@ void sti_crtc_disable_vblank(struct drm_device *drm_dev, unsigned int pipe)
 
 	/* free the resources of the pending requests */
 	if (compo->mixer[pipe]->pending_event) {
-		drm_vblank_put(drm_dev, pipe);
+		drm_crtc_vblank_put(crtc);
 		compo->mixer[pipe]->pending_event = NULL;
 	}
 }
-EXPORT_SYMBOL(sti_crtc_disable_vblank);
 
-static struct drm_crtc_funcs sti_crtc_funcs = {
+static const struct drm_crtc_funcs sti_crtc_funcs = {
 	.set_config = drm_atomic_helper_set_config,
 	.page_flip = drm_atomic_helper_page_flip,
 	.destroy = sti_crtc_destroy,
@@ -357,7 +359,6 @@ bool sti_crtc_is_main(struct drm_crtc *crtc)
 
 	return false;
 }
-EXPORT_SYMBOL(sti_crtc_is_main);
 
 int sti_crtc_init(struct drm_device *drm_dev, struct sti_mixer *mixer,
 		  struct drm_plane *primary, struct drm_plane *cursor)
diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c
index f8469967a0bfbb43dcf5faee539ac9b5d5b5f328..1469987949d88f8b43cfdd97990e925156a149ec 100644
--- a/drivers/gpu/drm/sti/sti_drv.c
+++ b/drivers/gpu/drm/sti/sti_drv.c
@@ -107,7 +107,7 @@ static int sti_atomic_commit(struct drm_device *drm,
 	return 0;
 }
 
-static struct drm_mode_config_funcs sti_mode_config_funcs = {
+static const struct drm_mode_config_funcs sti_mode_config_funcs = {
 	.fb_create = drm_fb_cma_create,
 	.atomic_check = drm_atomic_helper_check,
 	.atomic_commit = sti_atomic_commit,
@@ -123,8 +123,8 @@ static void sti_mode_config_init(struct drm_device *dev)
 	 * this value would be used to check framebuffer size limitation
 	 * at drm_mode_addfb().
 	 */
-	dev->mode_config.max_width = STI_MAX_FB_HEIGHT;
-	dev->mode_config.max_height = STI_MAX_FB_WIDTH;
+	dev->mode_config.max_width = STI_MAX_FB_WIDTH;
+	dev->mode_config.max_height = STI_MAX_FB_HEIGHT;
 
 	dev->mode_config.funcs = &sti_mode_config_funcs;
 }
@@ -160,11 +160,10 @@ static int sti_load(struct drm_device *dev, unsigned long flags)
 
 	drm_mode_config_reset(dev);
 
-#ifdef CONFIG_DRM_STI_FBDEV
 	drm_fbdev_cma_init(dev, 32,
 			   dev->mode_config.num_crtc,
 			   dev->mode_config.num_connector);
-#endif
+
 	return 0;
 }
 
@@ -287,7 +286,29 @@ static struct platform_driver sti_platform_driver = {
 	},
 };
 
-module_platform_driver(sti_platform_driver);
+static struct platform_driver * const drivers[] = {
+	&sti_tvout_driver,
+	&sti_vtac_driver,
+	&sti_hqvdp_driver,
+	&sti_hdmi_driver,
+	&sti_hda_driver,
+	&sti_dvo_driver,
+	&sti_vtg_driver,
+	&sti_compositor_driver,
+	&sti_platform_driver,
+};
+
+static int sti_drm_init(void)
+{
+	return platform_register_drivers(drivers, ARRAY_SIZE(drivers));
+}
+module_init(sti_drm_init);
+
+static void sti_drm_exit(void)
+{
+	platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
+}
+module_exit(sti_drm_exit);
 
 MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
 MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
diff --git a/drivers/gpu/drm/sti/sti_drv.h b/drivers/gpu/drm/sti/sti_drv.h
index 9372f69e1859ff96986b0cea5c795f3d3325c047..30ddc20841c343a6b1c904864107e6b4a4d732a0 100644
--- a/drivers/gpu/drm/sti/sti_drv.h
+++ b/drivers/gpu/drm/sti/sti_drv.h
@@ -32,4 +32,13 @@ struct sti_private {
 	} commit;
 };
 
+extern struct platform_driver sti_tvout_driver;
+extern struct platform_driver sti_vtac_driver;
+extern struct platform_driver sti_hqvdp_driver;
+extern struct platform_driver sti_hdmi_driver;
+extern struct platform_driver sti_hda_driver;
+extern struct platform_driver sti_dvo_driver;
+extern struct platform_driver sti_vtg_driver;
+extern struct platform_driver sti_compositor_driver;
+
 #endif
diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c
index d141d645bd13acd47c99b9c6b1de839e442fc280..45cbe2bf7dd60da4dbe6b513e21f8a890509c894 100644
--- a/drivers/gpu/drm/sti/sti_dvo.c
+++ b/drivers/gpu/drm/sti/sti_dvo.c
@@ -329,7 +329,8 @@ struct drm_encoder *sti_dvo_best_encoder(struct drm_connector *connector)
 	return dvo_connector->encoder;
 }
 
-static struct drm_connector_helper_funcs sti_dvo_connector_helper_funcs = {
+static const
+struct drm_connector_helper_funcs sti_dvo_connector_helper_funcs = {
 	.get_modes = sti_dvo_connector_get_modes,
 	.mode_valid = sti_dvo_connector_mode_valid,
 	.best_encoder = sti_dvo_best_encoder,
@@ -364,7 +365,7 @@ static void sti_dvo_connector_destroy(struct drm_connector *connector)
 	kfree(dvo_connector);
 }
 
-static struct drm_connector_funcs sti_dvo_connector_funcs = {
+static const struct drm_connector_funcs sti_dvo_connector_funcs = {
 	.dpms = drm_atomic_helper_connector_dpms,
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.detect = sti_dvo_connector_detect,
@@ -557,8 +558,6 @@ struct platform_driver sti_dvo_driver = {
 	.remove = sti_dvo_remove,
 };
 
-module_platform_driver(sti_dvo_driver);
-
 MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
 MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/sti/sti_gdp.c b/drivers/gpu/drm/sti/sti_gdp.c
index 9365670427ad26ef7224b085557c678769c63c6c..c85dc7d6b0053d2f45a673e43bbda6b99032bcf7 100644
--- a/drivers/gpu/drm/sti/sti_gdp.c
+++ b/drivers/gpu/drm/sti/sti_gdp.c
@@ -492,7 +492,7 @@ static void sti_gdp_atomic_update(struct drm_plane *drm_plane,
 		/* Register gdp callback */
 		if (sti_vtg_register_client(mixer->id == STI_MIXER_MAIN ?
 				compo->vtg_main : compo->vtg_aux,
-				&gdp->vtg_field_nb, mixer->id)) {
+				&gdp->vtg_field_nb, crtc)) {
 			DRM_ERROR("Cannot register VTG notifier\n");
 			return;
 		}
diff --git a/drivers/gpu/drm/sti/sti_hda.c b/drivers/gpu/drm/sti/sti_hda.c
index 598cd78b0b163cd2e86f92a68e5386325a3a357f..d735daccd4589b03528dd61eb350f9ded3b1da2d 100644
--- a/drivers/gpu/drm/sti/sti_hda.c
+++ b/drivers/gpu/drm/sti/sti_hda.c
@@ -589,7 +589,8 @@ struct drm_encoder *sti_hda_best_encoder(struct drm_connector *connector)
 	return hda_connector->encoder;
 }
 
-static struct drm_connector_helper_funcs sti_hda_connector_helper_funcs = {
+static const
+struct drm_connector_helper_funcs sti_hda_connector_helper_funcs = {
 	.get_modes = sti_hda_connector_get_modes,
 	.mode_valid = sti_hda_connector_mode_valid,
 	.best_encoder = sti_hda_best_encoder,
@@ -611,7 +612,7 @@ static void sti_hda_connector_destroy(struct drm_connector *connector)
 	kfree(hda_connector);
 }
 
-static struct drm_connector_funcs sti_hda_connector_funcs = {
+static const struct drm_connector_funcs sti_hda_connector_funcs = {
 	.dpms = drm_atomic_helper_connector_dpms,
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.detect = sti_hda_connector_detect,
@@ -784,8 +785,6 @@ struct platform_driver sti_hda_driver = {
 	.remove = sti_hda_remove,
 };
 
-module_platform_driver(sti_hda_driver);
-
 MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
 MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
index 09e29e43423e21e6326b54e159ed81ffc4114b86..cd501563c0cc58f83b9992e7e83e09e048dfd32a 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.c
+++ b/drivers/gpu/drm/sti/sti_hdmi.c
@@ -628,7 +628,8 @@ struct drm_encoder *sti_hdmi_best_encoder(struct drm_connector *connector)
 	return hdmi_connector->encoder;
 }
 
-static struct drm_connector_helper_funcs sti_hdmi_connector_helper_funcs = {
+static const
+struct drm_connector_helper_funcs sti_hdmi_connector_helper_funcs = {
 	.get_modes = sti_hdmi_connector_get_modes,
 	.mode_valid = sti_hdmi_connector_mode_valid,
 	.best_encoder = sti_hdmi_best_encoder,
@@ -663,7 +664,7 @@ static void sti_hdmi_connector_destroy(struct drm_connector *connector)
 	kfree(hdmi_connector);
 }
 
-static struct drm_connector_funcs sti_hdmi_connector_funcs = {
+static const struct drm_connector_funcs sti_hdmi_connector_funcs = {
 	.dpms = drm_atomic_helper_connector_dpms,
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.detect = sti_hdmi_connector_detect,
@@ -700,18 +701,17 @@ static int sti_hdmi_bind(struct device *dev, struct device *master, void *data)
 
 	encoder = sti_hdmi_find_encoder(drm_dev);
 	if (!encoder)
-		goto err_adapt;
+		return -EINVAL;
 
 	connector = devm_kzalloc(dev, sizeof(*connector), GFP_KERNEL);
 	if (!connector)
-		goto err_adapt;
-
+		return -EINVAL;
 
 	connector->hdmi = hdmi;
 
 	bridge = devm_kzalloc(dev, sizeof(*bridge), GFP_KERNEL);
 	if (!bridge)
-		goto err_adapt;
+		return -EINVAL;
 
 	bridge->driver_private = hdmi;
 	bridge->funcs = &sti_hdmi_bridge_funcs;
@@ -748,8 +748,7 @@ static int sti_hdmi_bind(struct device *dev, struct device *master, void *data)
 	drm_connector_unregister(drm_connector);
 err_connector:
 	drm_connector_cleanup(drm_connector);
-err_adapt:
-	put_device(&hdmi->ddc_adapt->dev);
+
 	return -EINVAL;
 }
 
@@ -794,13 +793,10 @@ static int sti_hdmi_probe(struct platform_device *pdev)
 
 	ddc = of_parse_phandle(pdev->dev.of_node, "ddc", 0);
 	if (ddc) {
-		hdmi->ddc_adapt = of_find_i2c_adapter_by_node(ddc);
-		if (!hdmi->ddc_adapt) {
-			of_node_put(ddc);
-			return -EPROBE_DEFER;
-		}
-
+		hdmi->ddc_adapt = of_get_i2c_adapter_by_node(ddc);
 		of_node_put(ddc);
+		if (!hdmi->ddc_adapt)
+			return -EPROBE_DEFER;
 	}
 
 	hdmi->dev = pdev->dev;
@@ -809,24 +805,29 @@ static int sti_hdmi_probe(struct platform_device *pdev)
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi-reg");
 	if (!res) {
 		DRM_ERROR("Invalid hdmi resource\n");
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto release_adapter;
 	}
 	hdmi->regs = devm_ioremap_nocache(dev, res->start, resource_size(res));
-	if (!hdmi->regs)
-		return -ENOMEM;
+	if (!hdmi->regs) {
+		ret = -ENOMEM;
+		goto release_adapter;
+	}
 
 	if (of_device_is_compatible(np, "st,stih416-hdmi")) {
 		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 						   "syscfg");
 		if (!res) {
 			DRM_ERROR("Invalid syscfg resource\n");
-			return -ENOMEM;
+			ret = -ENOMEM;
+			goto release_adapter;
 		}
 		hdmi->syscfg = devm_ioremap_nocache(dev, res->start,
 						    resource_size(res));
-		if (!hdmi->syscfg)
-			return -ENOMEM;
-
+		if (!hdmi->syscfg) {
+			ret = -ENOMEM;
+			goto release_adapter;
+		}
 	}
 
 	hdmi->phy_ops = (struct hdmi_phy_ops *)
@@ -836,25 +837,29 @@ static int sti_hdmi_probe(struct platform_device *pdev)
 	hdmi->clk_pix = devm_clk_get(dev, "pix");
 	if (IS_ERR(hdmi->clk_pix)) {
 		DRM_ERROR("Cannot get hdmi_pix clock\n");
-		return PTR_ERR(hdmi->clk_pix);
+		ret = PTR_ERR(hdmi->clk_pix);
+		goto release_adapter;
 	}
 
 	hdmi->clk_tmds = devm_clk_get(dev, "tmds");
 	if (IS_ERR(hdmi->clk_tmds)) {
 		DRM_ERROR("Cannot get hdmi_tmds clock\n");
-		return PTR_ERR(hdmi->clk_tmds);
+		ret = PTR_ERR(hdmi->clk_tmds);
+		goto release_adapter;
 	}
 
 	hdmi->clk_phy = devm_clk_get(dev, "phy");
 	if (IS_ERR(hdmi->clk_phy)) {
 		DRM_ERROR("Cannot get hdmi_phy clock\n");
-		return PTR_ERR(hdmi->clk_phy);
+		ret = PTR_ERR(hdmi->clk_phy);
+		goto release_adapter;
 	}
 
 	hdmi->clk_audio = devm_clk_get(dev, "audio");
 	if (IS_ERR(hdmi->clk_audio)) {
 		DRM_ERROR("Cannot get hdmi_audio clock\n");
-		return PTR_ERR(hdmi->clk_audio);
+		ret = PTR_ERR(hdmi->clk_audio);
+		goto release_adapter;
 	}
 
 	hdmi->hpd = readl(hdmi->regs + HDMI_STA) & HDMI_STA_HOT_PLUG;
@@ -867,7 +872,7 @@ static int sti_hdmi_probe(struct platform_device *pdev)
 			hdmi_irq_thread, IRQF_ONESHOT, dev_name(dev), hdmi);
 	if (ret) {
 		DRM_ERROR("Failed to register HDMI interrupt\n");
-		return ret;
+		goto release_adapter;
 	}
 
 	hdmi->reset = devm_reset_control_get(dev, "hdmi");
@@ -878,16 +883,20 @@ static int sti_hdmi_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, hdmi);
 
 	return component_add(&pdev->dev, &sti_hdmi_ops);
+
+ release_adapter:
+	i2c_put_adapter(hdmi->ddc_adapt);
+
+	return ret;
 }
 
 static int sti_hdmi_remove(struct platform_device *pdev)
 {
 	struct sti_hdmi *hdmi = dev_get_drvdata(&pdev->dev);
 
-	if (hdmi->ddc_adapt)
-		put_device(&hdmi->ddc_adapt->dev);
-
+	i2c_put_adapter(hdmi->ddc_adapt);
 	component_del(&pdev->dev, &sti_hdmi_ops);
+
 	return 0;
 }
 
@@ -901,8 +910,6 @@ struct platform_driver sti_hdmi_driver = {
 	.remove = sti_hdmi_remove,
 };
 
-module_platform_driver(sti_hdmi_driver);
-
 MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
 MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/sti/sti_hqvdp.c b/drivers/gpu/drm/sti/sti_hqvdp.c
index 7c8f9b8bfae10a27339b6693b462406500639c6c..ea0690bc77d5f72587ede24e1d1936d6dbd00578 100644
--- a/drivers/gpu/drm/sti/sti_hqvdp.c
+++ b/drivers/gpu/drm/sti/sti_hqvdp.c
@@ -628,6 +628,153 @@ static void sti_hqvdp_init(struct sti_hqvdp *hqvdp)
 	memset(hqvdp->hqvdp_cmd, 0, size);
 }
 
+static void sti_hqvdp_init_plugs(struct sti_hqvdp *hqvdp)
+{
+	/* Configure Plugs (same for RD & WR) */
+	writel(PLUG_PAGE_SIZE_256, hqvdp->regs + HQVDP_RD_PLUG_PAGE_SIZE);
+	writel(PLUG_MIN_OPC_8, hqvdp->regs + HQVDP_RD_PLUG_MIN_OPC);
+	writel(PLUG_MAX_OPC_64, hqvdp->regs + HQVDP_RD_PLUG_MAX_OPC);
+	writel(PLUG_MAX_CHK_2X, hqvdp->regs + HQVDP_RD_PLUG_MAX_CHK);
+	writel(PLUG_MAX_MSG_1X, hqvdp->regs + HQVDP_RD_PLUG_MAX_MSG);
+	writel(PLUG_MIN_SPACE_1, hqvdp->regs + HQVDP_RD_PLUG_MIN_SPACE);
+	writel(PLUG_CONTROL_ENABLE, hqvdp->regs + HQVDP_RD_PLUG_CONTROL);
+
+	writel(PLUG_PAGE_SIZE_256, hqvdp->regs + HQVDP_WR_PLUG_PAGE_SIZE);
+	writel(PLUG_MIN_OPC_8, hqvdp->regs + HQVDP_WR_PLUG_MIN_OPC);
+	writel(PLUG_MAX_OPC_64, hqvdp->regs + HQVDP_WR_PLUG_MAX_OPC);
+	writel(PLUG_MAX_CHK_2X, hqvdp->regs + HQVDP_WR_PLUG_MAX_CHK);
+	writel(PLUG_MAX_MSG_1X, hqvdp->regs + HQVDP_WR_PLUG_MAX_MSG);
+	writel(PLUG_MIN_SPACE_1, hqvdp->regs + HQVDP_WR_PLUG_MIN_SPACE);
+	writel(PLUG_CONTROL_ENABLE, hqvdp->regs + HQVDP_WR_PLUG_CONTROL);
+}
+
+/**
+ * sti_hqvdp_start_xp70
+ * @hqvdp: hqvdp pointer
+ *
+ * Run the xP70 initialization sequence
+ */
+static void sti_hqvdp_start_xp70(struct sti_hqvdp *hqvdp)
+{
+	const struct firmware *firmware;
+	u32 *fw_rd_plug, *fw_wr_plug, *fw_pmem, *fw_dmem;
+	u8 *data;
+	int i;
+	struct fw_header {
+		int rd_size;
+		int wr_size;
+		int pmem_size;
+		int dmem_size;
+	} *header;
+
+	DRM_DEBUG_DRIVER("\n");
+
+	if (hqvdp->xp70_initialized) {
+		DRM_INFO("HQVDP XP70 already initialized\n");
+		return;
+	}
+
+	/* Request firmware */
+	if (request_firmware(&firmware, HQVDP_FMW_NAME, hqvdp->dev)) {
+		DRM_ERROR("Can't get HQVDP firmware\n");
+		return;
+	}
+
+	/* Check firmware parts */
+	if (!firmware) {
+		DRM_ERROR("Firmware not available\n");
+		return;
+	}
+
+	header = (struct fw_header *)firmware->data;
+	if (firmware->size < sizeof(*header)) {
+		DRM_ERROR("Invalid firmware size (%d)\n", firmware->size);
+		goto out;
+	}
+	if ((sizeof(*header) + header->rd_size + header->wr_size +
+		header->pmem_size + header->dmem_size) != firmware->size) {
+		DRM_ERROR("Invalid fmw structure (%d+%d+%d+%d+%d != %d)\n",
+			  sizeof(*header), header->rd_size, header->wr_size,
+			  header->pmem_size, header->dmem_size,
+			  firmware->size);
+		goto out;
+	}
+
+	data = (u8 *)firmware->data;
+	data += sizeof(*header);
+	fw_rd_plug = (void *)data;
+	data += header->rd_size;
+	fw_wr_plug = (void *)data;
+	data += header->wr_size;
+	fw_pmem = (void *)data;
+	data += header->pmem_size;
+	fw_dmem = (void *)data;
+
+	/* Enable clock */
+	if (clk_prepare_enable(hqvdp->clk))
+		DRM_ERROR("Failed to prepare/enable HQVDP clk\n");
+
+	/* Reset */
+	writel(SW_RESET_CTRL_FULL, hqvdp->regs + HQVDP_MBX_SW_RESET_CTRL);
+
+	for (i = 0; i < POLL_MAX_ATTEMPT; i++) {
+		if (readl(hqvdp->regs + HQVDP_MBX_STARTUP_CTRL1)
+				& STARTUP_CTRL1_RST_DONE)
+			break;
+		msleep(POLL_DELAY_MS);
+	}
+	if (i == POLL_MAX_ATTEMPT) {
+		DRM_ERROR("Could not reset\n");
+		goto out;
+	}
+
+	/* Init Read & Write plugs */
+	for (i = 0; i < header->rd_size / 4; i++)
+		writel(fw_rd_plug[i], hqvdp->regs + HQVDP_RD_PLUG + i * 4);
+	for (i = 0; i < header->wr_size / 4; i++)
+		writel(fw_wr_plug[i], hqvdp->regs + HQVDP_WR_PLUG + i * 4);
+
+	sti_hqvdp_init_plugs(hqvdp);
+
+	/* Authorize Idle Mode */
+	writel(STARTUP_CTRL1_AUTH_IDLE, hqvdp->regs + HQVDP_MBX_STARTUP_CTRL1);
+
+	/* Prevent VTG interruption during the boot */
+	writel(SOFT_VSYNC_SW_CTRL_IRQ, hqvdp->regs + HQVDP_MBX_SOFT_VSYNC);
+	writel(0, hqvdp->regs + HQVDP_MBX_NEXT_CMD);
+
+	/* Download PMEM & DMEM */
+	for (i = 0; i < header->pmem_size / 4; i++)
+		writel(fw_pmem[i], hqvdp->regs + HQVDP_PMEM + i * 4);
+	for (i = 0; i < header->dmem_size / 4; i++)
+		writel(fw_dmem[i], hqvdp->regs + HQVDP_DMEM + i * 4);
+
+	/* Enable fetch */
+	writel(STARTUP_CTRL2_FETCH_EN, hqvdp->regs + HQVDP_MBX_STARTUP_CTRL2);
+
+	/* Wait end of boot */
+	for (i = 0; i < POLL_MAX_ATTEMPT; i++) {
+		if (readl(hqvdp->regs + HQVDP_MBX_INFO_XP70)
+				& INFO_XP70_FW_READY)
+			break;
+		msleep(POLL_DELAY_MS);
+	}
+	if (i == POLL_MAX_ATTEMPT) {
+		DRM_ERROR("Could not boot\n");
+		goto out;
+	}
+
+	/* Launch Vsync */
+	writel(SOFT_VSYNC_HW, hqvdp->regs + HQVDP_MBX_SOFT_VSYNC);
+
+	DRM_INFO("HQVDP XP70 initialized\n");
+
+	hqvdp->xp70_initialized = true;
+
+out:
+	release_firmware(firmware);
+}
+
 static void sti_hqvdp_atomic_update(struct drm_plane *drm_plane,
 				    struct drm_plane_state *oldstate)
 {
@@ -754,6 +901,9 @@ static void sti_hqvdp_atomic_update(struct drm_plane *drm_plane,
 	sti_hqvdp_update_hvsrc(HVSRC_VERT, scale_v, &cmd->hvsrc);
 
 	if (first_prepare) {
+		/* Start HQVDP XP70 coprocessor */
+		sti_hqvdp_start_xp70(hqvdp);
+
 		/* Prevent VTG shutdown */
 		if (clk_prepare_enable(hqvdp->clk_pix_main)) {
 			DRM_ERROR("Failed to prepare/enable pix main clk\n");
@@ -763,7 +913,7 @@ static void sti_hqvdp_atomic_update(struct drm_plane *drm_plane,
 		/* Register VTG Vsync callback to handle bottom fields */
 		if (sti_vtg_register_client(hqvdp->vtg,
 					    &hqvdp->vtg_nb,
-					    mixer->id)) {
+					    crtc)) {
 			DRM_ERROR("Cannot register VTG notifier\n");
 			return;
 		}
@@ -836,168 +986,16 @@ static struct drm_plane *sti_hqvdp_create(struct drm_device *drm_dev,
 	return &hqvdp->plane.drm_plane;
 }
 
-static void sti_hqvdp_init_plugs(struct sti_hqvdp *hqvdp)
-{
-	/* Configure Plugs (same for RD & WR) */
-	writel(PLUG_PAGE_SIZE_256, hqvdp->regs + HQVDP_RD_PLUG_PAGE_SIZE);
-	writel(PLUG_MIN_OPC_8, hqvdp->regs + HQVDP_RD_PLUG_MIN_OPC);
-	writel(PLUG_MAX_OPC_64, hqvdp->regs + HQVDP_RD_PLUG_MAX_OPC);
-	writel(PLUG_MAX_CHK_2X, hqvdp->regs + HQVDP_RD_PLUG_MAX_CHK);
-	writel(PLUG_MAX_MSG_1X, hqvdp->regs + HQVDP_RD_PLUG_MAX_MSG);
-	writel(PLUG_MIN_SPACE_1, hqvdp->regs + HQVDP_RD_PLUG_MIN_SPACE);
-	writel(PLUG_CONTROL_ENABLE, hqvdp->regs + HQVDP_RD_PLUG_CONTROL);
-
-	writel(PLUG_PAGE_SIZE_256, hqvdp->regs + HQVDP_WR_PLUG_PAGE_SIZE);
-	writel(PLUG_MIN_OPC_8, hqvdp->regs + HQVDP_WR_PLUG_MIN_OPC);
-	writel(PLUG_MAX_OPC_64, hqvdp->regs + HQVDP_WR_PLUG_MAX_OPC);
-	writel(PLUG_MAX_CHK_2X, hqvdp->regs + HQVDP_WR_PLUG_MAX_CHK);
-	writel(PLUG_MAX_MSG_1X, hqvdp->regs + HQVDP_WR_PLUG_MAX_MSG);
-	writel(PLUG_MIN_SPACE_1, hqvdp->regs + HQVDP_WR_PLUG_MIN_SPACE);
-	writel(PLUG_CONTROL_ENABLE, hqvdp->regs + HQVDP_WR_PLUG_CONTROL);
-}
-
-/**
- * sti_hqvdp_start_xp70
- * @firmware: firmware found
- * @ctxt:     hqvdp structure
- *
- * Run the xP70 initialization sequence
- */
-static void sti_hqvdp_start_xp70(const struct firmware *firmware, void *ctxt)
-{
-	struct sti_hqvdp *hqvdp = ctxt;
-	u32 *fw_rd_plug, *fw_wr_plug, *fw_pmem, *fw_dmem;
-	u8 *data;
-	int i;
-	struct fw_header {
-		int rd_size;
-		int wr_size;
-		int pmem_size;
-		int dmem_size;
-	} *header;
-
-	DRM_DEBUG_DRIVER("\n");
-
-	if (hqvdp->xp70_initialized) {
-		DRM_INFO("HQVDP XP70 already initialized\n");
-		return;
-	}
-
-	/* Check firmware parts */
-	if (!firmware) {
-		DRM_ERROR("Firmware not available\n");
-		return;
-	}
-
-	header = (struct fw_header *) firmware->data;
-	if (firmware->size < sizeof(*header)) {
-		DRM_ERROR("Invalid firmware size (%d)\n", firmware->size);
-		goto out;
-	}
-	if ((sizeof(*header) + header->rd_size + header->wr_size +
-		header->pmem_size + header->dmem_size) != firmware->size) {
-		DRM_ERROR("Invalid fmw structure (%d+%d+%d+%d+%d != %d)\n",
-			   sizeof(*header), header->rd_size, header->wr_size,
-			   header->pmem_size, header->dmem_size,
-			   firmware->size);
-		goto out;
-	}
-
-	data = (u8 *) firmware->data;
-	data += sizeof(*header);
-	fw_rd_plug = (void *) data;
-	data += header->rd_size;
-	fw_wr_plug = (void *) data;
-	data += header->wr_size;
-	fw_pmem = (void *) data;
-	data += header->pmem_size;
-	fw_dmem = (void *) data;
-
-	/* Enable clock */
-	if (clk_prepare_enable(hqvdp->clk))
-		DRM_ERROR("Failed to prepare/enable HQVDP clk\n");
-
-	/* Reset */
-	writel(SW_RESET_CTRL_FULL, hqvdp->regs + HQVDP_MBX_SW_RESET_CTRL);
-
-	for (i = 0; i < POLL_MAX_ATTEMPT; i++) {
-		if (readl(hqvdp->regs + HQVDP_MBX_STARTUP_CTRL1)
-				& STARTUP_CTRL1_RST_DONE)
-			break;
-		msleep(POLL_DELAY_MS);
-	}
-	if (i == POLL_MAX_ATTEMPT) {
-		DRM_ERROR("Could not reset\n");
-		goto out;
-	}
-
-	/* Init Read & Write plugs */
-	for (i = 0; i < header->rd_size / 4; i++)
-		writel(fw_rd_plug[i], hqvdp->regs + HQVDP_RD_PLUG + i * 4);
-	for (i = 0; i < header->wr_size / 4; i++)
-		writel(fw_wr_plug[i], hqvdp->regs + HQVDP_WR_PLUG + i * 4);
-
-	sti_hqvdp_init_plugs(hqvdp);
-
-	/* Authorize Idle Mode */
-	writel(STARTUP_CTRL1_AUTH_IDLE, hqvdp->regs + HQVDP_MBX_STARTUP_CTRL1);
-
-	/* Prevent VTG interruption during the boot */
-	writel(SOFT_VSYNC_SW_CTRL_IRQ, hqvdp->regs + HQVDP_MBX_SOFT_VSYNC);
-	writel(0, hqvdp->regs + HQVDP_MBX_NEXT_CMD);
-
-	/* Download PMEM & DMEM */
-	for (i = 0; i < header->pmem_size / 4; i++)
-		writel(fw_pmem[i], hqvdp->regs + HQVDP_PMEM + i * 4);
-	for (i = 0; i < header->dmem_size / 4; i++)
-		writel(fw_dmem[i], hqvdp->regs + HQVDP_DMEM + i * 4);
-
-	/* Enable fetch */
-	writel(STARTUP_CTRL2_FETCH_EN, hqvdp->regs + HQVDP_MBX_STARTUP_CTRL2);
-
-	/* Wait end of boot */
-	for (i = 0; i < POLL_MAX_ATTEMPT; i++) {
-		if (readl(hqvdp->regs + HQVDP_MBX_INFO_XP70)
-				& INFO_XP70_FW_READY)
-			break;
-		msleep(POLL_DELAY_MS);
-	}
-	if (i == POLL_MAX_ATTEMPT) {
-		DRM_ERROR("Could not boot\n");
-		goto out;
-	}
-
-	/* Launch Vsync */
-	writel(SOFT_VSYNC_HW, hqvdp->regs + HQVDP_MBX_SOFT_VSYNC);
-
-	DRM_INFO("HQVDP XP70 initialized\n");
-
-	hqvdp->xp70_initialized = true;
-
-out:
-	release_firmware(firmware);
-}
-
 int sti_hqvdp_bind(struct device *dev, struct device *master, void *data)
 {
 	struct sti_hqvdp *hqvdp = dev_get_drvdata(dev);
 	struct drm_device *drm_dev = data;
 	struct drm_plane *plane;
-	int err;
 
 	DRM_DEBUG_DRIVER("\n");
 
 	hqvdp->drm_dev = drm_dev;
 
-	/* Request for firmware */
-	err = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
-				HQVDP_FMW_NAME,	hqvdp->dev,
-				GFP_KERNEL, hqvdp, sti_hqvdp_start_xp70);
-	if (err) {
-		DRM_ERROR("Can't get HQVDP firmware\n");
-		return err;
-	}
-
 	/* Create HQVDP plane once xp70 is initialized */
 	plane = sti_hqvdp_create(drm_dev, hqvdp->dev, STI_HQVDP_0);
 	if (!plane)
@@ -1090,8 +1088,6 @@ struct platform_driver sti_hqvdp_driver = {
 	.remove = sti_hqvdp_remove,
 };
 
-module_platform_driver(sti_hqvdp_driver);
-
 MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
 MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/sti/sti_mixer.c b/drivers/gpu/drm/sti/sti_mixer.c
index 0182e936500427e8fd798251c6dccdd340b87495..49db835dce036a3a78fc9cb13e1fdd5173fc7d7a 100644
--- a/drivers/gpu/drm/sti/sti_mixer.c
+++ b/drivers/gpu/drm/sti/sti_mixer.c
@@ -10,6 +10,11 @@
 #include "sti_mixer.h"
 #include "sti_vtg.h"
 
+/* Module parameter to set the background color of the mixer */
+static unsigned int bkg_color = 0x000000;
+MODULE_PARM_DESC(bkgcolor, "Value of the background color 0xRRGGBB");
+module_param_named(bkgcolor, bkg_color, int, 0644);
+
 /* Identity: G=Y , B=Cb , R=Cr */
 static const u32 mixerColorSpaceMatIdentity[] = {
 	0x10000000, 0x00000000, 0x10000000, 0x00001000,
@@ -58,7 +63,6 @@ const char *sti_mixer_to_str(struct sti_mixer *mixer)
 		return "<UNKNOWN MIXER>";
 	}
 }
-EXPORT_SYMBOL(sti_mixer_to_str);
 
 static inline u32 sti_mixer_reg_read(struct sti_mixer *mixer, u32 reg_id)
 {
@@ -81,11 +85,9 @@ void sti_mixer_set_background_status(struct sti_mixer *mixer, bool enable)
 }
 
 static void sti_mixer_set_background_color(struct sti_mixer *mixer,
-					   u8 red, u8 green, u8 blue)
+					   unsigned int rgb)
 {
-	u32 val = (red << 16) | (green << 8) | blue;
-
-	sti_mixer_reg_write(mixer, GAM_MIXER_BKC, val);
+	sti_mixer_reg_write(mixer, GAM_MIXER_BKC, rgb);
 }
 
 static void sti_mixer_set_background_area(struct sti_mixer *mixer,
@@ -175,7 +177,7 @@ int sti_mixer_active_video_area(struct sti_mixer *mixer,
 	sti_mixer_reg_write(mixer, GAM_MIXER_AVO, ydo << 16 | xdo);
 	sti_mixer_reg_write(mixer, GAM_MIXER_AVS, yds << 16 | xds);
 
-	sti_mixer_set_background_color(mixer, 0xFF, 0, 0);
+	sti_mixer_set_background_color(mixer, bkg_color);
 
 	sti_mixer_set_background_area(mixer, mode);
 	sti_mixer_set_background_status(mixer, true);
diff --git a/drivers/gpu/drm/sti/sti_plane.c b/drivers/gpu/drm/sti/sti_plane.c
index d5c5e91f2956038d2daa3b180051c635bfd6d0e4..2e5c751910c579b70f90836d9a7973bd2f086921 100644
--- a/drivers/gpu/drm/sti/sti_plane.c
+++ b/drivers/gpu/drm/sti/sti_plane.c
@@ -42,7 +42,6 @@ const char *sti_plane_to_str(struct sti_plane *plane)
 		return "<UNKNOWN PLANE>";
 	}
 }
-EXPORT_SYMBOL(sti_plane_to_str);
 
 static void sti_plane_destroy(struct drm_plane *drm_plane)
 {
@@ -108,7 +107,6 @@ void sti_plane_init_property(struct sti_plane *plane,
 			 plane->drm_plane.base.id,
 			 sti_plane_to_str(plane), plane->zorder);
 }
-EXPORT_SYMBOL(sti_plane_init_property);
 
 struct drm_plane_funcs sti_plane_helpers_funcs = {
 	.update_plane = drm_atomic_helper_update_plane,
@@ -119,4 +117,3 @@ struct drm_plane_funcs sti_plane_helpers_funcs = {
 	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
 };
-EXPORT_SYMBOL(sti_plane_helpers_funcs);
diff --git a/drivers/gpu/drm/sti/sti_tvout.c b/drivers/gpu/drm/sti/sti_tvout.c
index c1aac8e66fb5024a626aa5a37bf99264beb0d870..c8a4c5dae2b6f2010365d4e63c43ec2b4d8c8659 100644
--- a/drivers/gpu/drm/sti/sti_tvout.c
+++ b/drivers/gpu/drm/sti/sti_tvout.c
@@ -735,8 +735,6 @@ struct platform_driver sti_tvout_driver = {
 	.remove = sti_tvout_remove,
 };
 
-module_platform_driver(sti_tvout_driver);
-
 MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
 MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/sti/sti_vtac.c b/drivers/gpu/drm/sti/sti_vtac.c
index 97bcdac23ae1f0733d87b3cc6f3b071834d1bdba..b1eb0d77630dfce30ee13373371edfbb32c10dad 100644
--- a/drivers/gpu/drm/sti/sti_vtac.c
+++ b/drivers/gpu/drm/sti/sti_vtac.c
@@ -216,8 +216,6 @@ struct platform_driver sti_vtac_driver = {
 	.remove = sti_vtac_remove,
 };
 
-module_platform_driver(sti_vtac_driver);
-
 MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
 MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/sti/sti_vtg.c b/drivers/gpu/drm/sti/sti_vtg.c
index aa809713770166537db8f124dff3a2934e7492c9..d56630c60039fead79ca37f1ed52b7614f9e8aee 100644
--- a/drivers/gpu/drm/sti/sti_vtg.c
+++ b/drivers/gpu/drm/sti/sti_vtg.c
@@ -79,7 +79,7 @@ LIST_HEAD(vtg_lookup);
  * @irq: VTG irq
  * @type: VTG type (main or aux)
  * @notifier_list: notifier callback
- * @crtc_id: the crtc id for vblank event
+ * @crtc: the CRTC for vblank event
  * @slave: slave vtg
  * @link: List node to link the structure in lookup list
  */
@@ -90,7 +90,7 @@ struct sti_vtg {
 	int irq;
 	u32 irq_status;
 	struct raw_notifier_head notifier_list;
-	int crtc_id;
+	struct drm_crtc *crtc;
 	struct sti_vtg *slave;
 	struct list_head link;
 };
@@ -110,7 +110,6 @@ struct sti_vtg *of_vtg_find(struct device_node *np)
 	}
 	return NULL;
 }
-EXPORT_SYMBOL(of_vtg_find);
 
 static void vtg_reset(struct sti_vtg *vtg)
 {
@@ -242,7 +241,6 @@ void sti_vtg_set_config(struct sti_vtg *vtg,
 	else
 		vtg_enable_irq(vtg);
 }
-EXPORT_SYMBOL(sti_vtg_set_config);
 
 /**
  * sti_vtg_get_line_number
@@ -265,7 +263,6 @@ u32 sti_vtg_get_line_number(struct drm_display_mode mode, int y)
 
 	return start_line + y;
 }
-EXPORT_SYMBOL(sti_vtg_get_line_number);
 
 /**
  * sti_vtg_get_pixel_number
@@ -281,18 +278,16 @@ u32 sti_vtg_get_pixel_number(struct drm_display_mode mode, int x)
 {
 	return mode.htotal - mode.hsync_start + x;
 }
-EXPORT_SYMBOL(sti_vtg_get_pixel_number);
 
-int sti_vtg_register_client(struct sti_vtg *vtg,
-		struct notifier_block *nb, int crtc_id)
+int sti_vtg_register_client(struct sti_vtg *vtg, struct notifier_block *nb,
+			    struct drm_crtc *crtc)
 {
 	if (vtg->slave)
-		return sti_vtg_register_client(vtg->slave, nb, crtc_id);
+		return sti_vtg_register_client(vtg->slave, nb, crtc);
 
-	vtg->crtc_id = crtc_id;
+	vtg->crtc = crtc;
 	return raw_notifier_chain_register(&vtg->notifier_list, nb);
 }
-EXPORT_SYMBOL(sti_vtg_register_client);
 
 int sti_vtg_unregister_client(struct sti_vtg *vtg, struct notifier_block *nb)
 {
@@ -301,7 +296,6 @@ int sti_vtg_unregister_client(struct sti_vtg *vtg, struct notifier_block *nb)
 
 	return raw_notifier_chain_unregister(&vtg->notifier_list, nb);
 }
-EXPORT_SYMBOL(sti_vtg_unregister_client);
 
 static irqreturn_t vtg_irq_thread(int irq, void *arg)
 {
@@ -311,7 +305,7 @@ static irqreturn_t vtg_irq_thread(int irq, void *arg)
 	event = (vtg->irq_status & VTG_IRQ_TOP) ?
 		VTG_TOP_FIELD_EVENT : VTG_BOTTOM_FIELD_EVENT;
 
-	raw_notifier_call_chain(&vtg->notifier_list, event, &vtg->crtc_id);
+	raw_notifier_call_chain(&vtg->notifier_list, event, vtg->crtc);
 
 	return IRQ_HANDLED;
 }
@@ -406,8 +400,6 @@ struct platform_driver sti_vtg_driver = {
 	.remove = vtg_remove,
 };
 
-module_platform_driver(sti_vtg_driver);
-
 MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
 MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/sti/sti_vtg.h b/drivers/gpu/drm/sti/sti_vtg.h
index e84d23f1f57ff71912eac3759f0691625eb64776..cd2439f89d05d6b183f36a529526b3fa33d46b86 100644
--- a/drivers/gpu/drm/sti/sti_vtg.h
+++ b/drivers/gpu/drm/sti/sti_vtg.h
@@ -17,8 +17,8 @@ struct notifier_block;
 struct sti_vtg *of_vtg_find(struct device_node *np);
 void sti_vtg_set_config(struct sti_vtg *vtg,
 		const struct drm_display_mode *mode);
-int sti_vtg_register_client(struct sti_vtg *vtg,
-		struct notifier_block *nb, int crtc_id);
+int sti_vtg_register_client(struct sti_vtg *vtg, struct notifier_block *nb,
+			    struct drm_crtc *crtc);
 int sti_vtg_unregister_client(struct sti_vtg *vtg,
 		struct notifier_block *nb);