diff --git a/msm/msm_drv.c b/msm/msm_drv.c index 9eb1590540..70692994f5 100644 --- a/msm/msm_drv.c +++ b/msm/msm_drv.c @@ -397,13 +397,9 @@ static int msm_drm_uninit(struct device *dev) struct msm_vm_client_entry *client_entry, *tmp; int i; - /* We must cancel and cleanup any pending vblank enable/disable - * work before drm_irq_uninstall() to avoid work re-enabling an - * irq after uninstall has disabled it. - */ - flush_workqueue(priv->wq); - destroy_workqueue(priv->wq); + pm_runtime_get_sync(dev); + /* clean up display commit/event worker threads */ for (i = 0; i < priv->num_crtcs; i++) { if (priv->disp_thread[i].thread) { @@ -420,7 +416,11 @@ static int msm_drm_uninit(struct device *dev) } drm_kms_helper_poll_fini(ddev); + if (kms && kms->funcs) + kms->funcs->debugfs_destroy(kms); + sde_dbg_destroy(); + debugfs_remove_recursive(priv->debug_root); drm_mode_config_cleanup(ddev); if (priv->registered) { @@ -433,11 +433,7 @@ static int msm_drm_uninit(struct device *dev) msm_fbdev_free(ddev); #endif drm_atomic_helper_shutdown(ddev); - drm_mode_config_cleanup(ddev); - - pm_runtime_get_sync(dev); drm_irq_uninstall(ddev); - pm_runtime_put_sync(dev); if (kms && kms->funcs) kms->funcs->destroy(kms); @@ -450,9 +446,7 @@ static int msm_drm_uninit(struct device *dev) } component_unbind_all(dev, ddev); - - sde_dbg_destroy(); - debugfs_remove_recursive(priv->debug_root); + pm_runtime_put_sync(dev); sde_power_resource_deinit(pdev, &priv->phandle); @@ -470,6 +464,7 @@ static int msm_drm_uninit(struct device *dev) msm_mdss_destroy(ddev); ddev->dev_private = NULL; + destroy_workqueue(priv->wq); kfree(priv); drm_dev_put(ddev); @@ -2090,8 +2085,6 @@ static int msm_pdev_remove(struct platform_device *pdev) component_master_del(&pdev->dev, &msm_drm_ops); of_platform_depopulate(&pdev->dev); - msm_drm_unbind(&pdev->dev); - component_master_del(&pdev->dev, &msm_drm_ops); return 0; } diff --git a/msm/msm_kms.h b/msm/msm_kms.h index b4b8a0d2c5..08b420cebd 100644 --- a/msm/msm_kms.h +++ b/msm/msm_kms.h @@ -116,6 +116,8 @@ struct msm_kms_funcs { /* debugfs: */ int (*debugfs_init)(struct msm_kms *kms, struct drm_minor *minor); #endif + /* destroys debugfs */ + void (*debugfs_destroy)(struct msm_kms *kms); /* handle continuous splash */ int (*cont_splash_config)(struct msm_kms *kms); /* check for continuous splash status */ diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index dff9c12d4a..10b3340594 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -546,6 +546,7 @@ void sde_encoder_destroy(struct drm_encoder *drm_enc) { struct sde_encoder_virt *sde_enc = NULL; int i = 0; + unsigned int num_encs; if (!drm_enc) { SDE_ERROR("invalid encoder\n"); @@ -554,21 +555,29 @@ void sde_encoder_destroy(struct drm_encoder *drm_enc) sde_enc = to_sde_encoder_virt(drm_enc); SDE_DEBUG_ENC(sde_enc, "\n"); + num_encs = sde_enc->num_phys_encs; mutex_lock(&sde_enc->enc_lock); sde_rsc_client_destroy(sde_enc->rsc_client); - for (i = 0; i < sde_enc->num_phys_encs; i++) { + for (i = 0; i < num_encs; i++) { struct sde_encoder_phys *phys; phys = sde_enc->phys_vid_encs[i]; if (phys && phys->ops.destroy) { phys->ops.destroy(phys); --sde_enc->num_phys_encs; - sde_enc->phys_encs[i] = NULL; + sde_enc->phys_vid_encs[i] = NULL; } phys = sde_enc->phys_cmd_encs[i]; + if (phys && phys->ops.destroy) { + phys->ops.destroy(phys); + --sde_enc->num_phys_encs; + sde_enc->phys_cmd_encs[i] = NULL; + } + + phys = sde_enc->phys_encs[i]; if (phys && phys->ops.destroy) { phys->ops.destroy(phys); --sde_enc->num_phys_encs; diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index 04ccb075e1..a112818d77 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -161,8 +161,10 @@ static int _sde_debugfs_init(struct sde_kms *sde_kms) return 0; } -static void _sde_debugfs_destroy(struct sde_kms *sde_kms) +static void sde_kms_debugfs_destroy(struct msm_kms *kms) { + struct sde_kms *sde_kms = to_sde_kms(kms); + /* don't need to NULL check debugfs_root */ if (sde_kms) { sde_debugfs_vbif_destroy(sde_kms); @@ -189,7 +191,7 @@ static int _sde_debugfs_init(struct sde_kms *sde_kms) return 0; } -static void _sde_debugfs_destroy(struct sde_kms *sde_kms) +static void sde_kms_debugfs_destroy(struct msm_kms *kms) { } @@ -1806,10 +1808,6 @@ static void _sde_kms_hw_destroy(struct sde_kms *sde_kms, _sde_kms_unmap_all_splash_regions(sde_kms); - /* safe to call these more than once during shutdown */ - _sde_debugfs_destroy(sde_kms); - _sde_kms_mmu_destroy(sde_kms); - if (sde_kms->catalog) { for (i = 0; i < sde_kms->catalog->vbif_count; i++) { u32 vbif_idx = sde_kms->catalog->vbif[i].id; @@ -1848,6 +1846,7 @@ static void _sde_kms_hw_destroy(struct sde_kms *sde_kms, sde_kms->mmio = NULL; sde_reg_dma_deinit(); + _sde_kms_mmu_destroy(sde_kms); } int sde_kms_mmu_detach(struct sde_kms *sde_kms, bool secure_only) @@ -2936,6 +2935,7 @@ static const struct msm_kms_funcs kms_funcs = { .pm_suspend = sde_kms_pm_suspend, .pm_resume = sde_kms_pm_resume, .destroy = sde_kms_destroy, + .debugfs_destroy = sde_kms_debugfs_destroy, .cont_splash_config = sde_kms_cont_splash_config, .register_events = _sde_kms_register_events, .get_address_space = _sde_kms_get_address_space,