diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 588d4ba0d8cf74ada6f8ab203b64d47b004cec27..93ab5395c838f38e7ca673fa4d03eb820a33035f 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -93,8 +93,11 @@ static int tegra_plane_disable(struct drm_plane *plane) static void tegra_plane_destroy(struct drm_plane *plane) { + struct tegra_plane *p = to_tegra_plane(plane); + tegra_plane_disable(plane); drm_plane_cleanup(plane); + kfree(p); } static const struct drm_plane_funcs tegra_plane_funcs = { @@ -120,7 +123,7 @@ static int tegra_dc_add_planes(struct drm_device *drm, struct tegra_dc *dc) for (i = 0; i < 2; i++) { struct tegra_plane *plane; - plane = devm_kzalloc(drm->dev, sizeof(*plane), GFP_KERNEL); + plane = kzalloc(sizeof(*plane), GFP_KERNEL); if (!plane) return -ENOMEM; @@ -129,8 +132,10 @@ static int tegra_dc_add_planes(struct drm_device *drm, struct tegra_dc *dc) err = drm_plane_init(drm, &plane->base, 1 << dc->pipe, &tegra_plane_funcs, plane_formats, ARRAY_SIZE(plane_formats), false); - if (err < 0) + if (err < 0) { + kfree(plane); return err; + } } return 0; @@ -251,14 +256,26 @@ static int tegra_dc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, return 0; } +static void drm_crtc_clear(struct drm_crtc *crtc) +{ + memset(crtc, 0, sizeof(*crtc)); +} + +static void tegra_dc_destroy(struct drm_crtc *crtc) +{ + drm_crtc_cleanup(crtc); + drm_crtc_clear(crtc); +} + static const struct drm_crtc_funcs tegra_crtc_funcs = { .page_flip = tegra_dc_page_flip, .set_config = drm_crtc_helper_set_config, - .destroy = drm_crtc_cleanup, + .destroy = tegra_dc_destroy, }; static void tegra_crtc_disable(struct drm_crtc *crtc) { + struct tegra_dc *dc = to_tegra_dc(crtc); struct drm_device *drm = crtc->dev; struct drm_plane *plane; @@ -273,6 +290,8 @@ static void tegra_crtc_disable(struct drm_crtc *crtc) } } } + + drm_vblank_off(drm, dc->pipe); } static bool tegra_crtc_mode_fixup(struct drm_crtc *crtc, diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index c2db409bbd63d90a0504e8d9377d52ce747e11e4..96dea0a8313988e07e8b5a78788c0ef554655a5e 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -72,13 +72,13 @@ static int tegra_drm_unload(struct drm_device *drm) drm_kms_helper_poll_fini(drm); tegra_drm_fb_exit(drm); + drm_vblank_cleanup(drm); + drm_mode_config_cleanup(drm); err = host1x_device_exit(device); if (err < 0) return err; - drm_mode_config_cleanup(drm); - return 0; } diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c index 8f40fa646cecaa76104e8767bb4adde52ab9d00a..591d3b0186d8a804f4bdd23851798fb54bbf46a3 100644 --- a/drivers/gpu/drm/tegra/output.c +++ b/drivers/gpu/drm/tegra/output.c @@ -79,10 +79,16 @@ tegra_connector_detect(struct drm_connector *connector, bool force) return status; } +static void drm_connector_clear(struct drm_connector *connector) +{ + memset(connector, 0, sizeof(*connector)); +} + static void tegra_connector_destroy(struct drm_connector *connector) { drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); + drm_connector_clear(connector); } static const struct drm_connector_funcs connector_funcs = { @@ -92,9 +98,15 @@ static const struct drm_connector_funcs connector_funcs = { .destroy = tegra_connector_destroy, }; +static void drm_encoder_clear(struct drm_encoder *encoder) +{ + memset(encoder, 0, sizeof(*encoder)); +} + static void tegra_encoder_destroy(struct drm_encoder *encoder) { drm_encoder_cleanup(encoder); + drm_encoder_clear(encoder); } static const struct drm_encoder_funcs encoder_funcs = {