disp: msm: fix driver unload issues in gki config

Resolves segmentation fault during driver unload in GKI
configuration, caused by repeated debugfs destroy calls.
Also removes redundant unload calls.

Change-Id: I20a8efc1916b9a60766f9c7714a4b458aa518566
Signed-off-by: Orion Brody <obrody@codeaurora.org>
This commit is contained in:
Orion Brody
2020-06-03 12:02:08 -07:00
parent a995ee8ca1
commit 66f04c4716
4 changed files with 27 additions and 23 deletions

View File

@@ -397,13 +397,9 @@ static int msm_drm_uninit(struct device *dev)
struct msm_vm_client_entry *client_entry, *tmp; struct msm_vm_client_entry *client_entry, *tmp;
int i; 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); flush_workqueue(priv->wq);
destroy_workqueue(priv->wq); pm_runtime_get_sync(dev);
/* clean up display commit/event worker threads */ /* clean up display commit/event worker threads */
for (i = 0; i < priv->num_crtcs; i++) { for (i = 0; i < priv->num_crtcs; i++) {
if (priv->disp_thread[i].thread) { if (priv->disp_thread[i].thread) {
@@ -420,7 +416,11 @@ static int msm_drm_uninit(struct device *dev)
} }
drm_kms_helper_poll_fini(ddev); 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); drm_mode_config_cleanup(ddev);
if (priv->registered) { if (priv->registered) {
@@ -433,11 +433,7 @@ static int msm_drm_uninit(struct device *dev)
msm_fbdev_free(ddev); msm_fbdev_free(ddev);
#endif #endif
drm_atomic_helper_shutdown(ddev); drm_atomic_helper_shutdown(ddev);
drm_mode_config_cleanup(ddev);
pm_runtime_get_sync(dev);
drm_irq_uninstall(ddev); drm_irq_uninstall(ddev);
pm_runtime_put_sync(dev);
if (kms && kms->funcs) if (kms && kms->funcs)
kms->funcs->destroy(kms); kms->funcs->destroy(kms);
@@ -450,9 +446,7 @@ static int msm_drm_uninit(struct device *dev)
} }
component_unbind_all(dev, ddev); component_unbind_all(dev, ddev);
pm_runtime_put_sync(dev);
sde_dbg_destroy();
debugfs_remove_recursive(priv->debug_root);
sde_power_resource_deinit(pdev, &priv->phandle); sde_power_resource_deinit(pdev, &priv->phandle);
@@ -470,6 +464,7 @@ static int msm_drm_uninit(struct device *dev)
msm_mdss_destroy(ddev); msm_mdss_destroy(ddev);
ddev->dev_private = NULL; ddev->dev_private = NULL;
destroy_workqueue(priv->wq);
kfree(priv); kfree(priv);
drm_dev_put(ddev); 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); component_master_del(&pdev->dev, &msm_drm_ops);
of_platform_depopulate(&pdev->dev); of_platform_depopulate(&pdev->dev);
msm_drm_unbind(&pdev->dev);
component_master_del(&pdev->dev, &msm_drm_ops);
return 0; return 0;
} }

View File

@@ -116,6 +116,8 @@ struct msm_kms_funcs {
/* debugfs: */ /* debugfs: */
int (*debugfs_init)(struct msm_kms *kms, struct drm_minor *minor); int (*debugfs_init)(struct msm_kms *kms, struct drm_minor *minor);
#endif #endif
/* destroys debugfs */
void (*debugfs_destroy)(struct msm_kms *kms);
/* handle continuous splash */ /* handle continuous splash */
int (*cont_splash_config)(struct msm_kms *kms); int (*cont_splash_config)(struct msm_kms *kms);
/* check for continuous splash status */ /* check for continuous splash status */

View File

@@ -546,6 +546,7 @@ void sde_encoder_destroy(struct drm_encoder *drm_enc)
{ {
struct sde_encoder_virt *sde_enc = NULL; struct sde_encoder_virt *sde_enc = NULL;
int i = 0; int i = 0;
unsigned int num_encs;
if (!drm_enc) { if (!drm_enc) {
SDE_ERROR("invalid encoder\n"); 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_enc = to_sde_encoder_virt(drm_enc);
SDE_DEBUG_ENC(sde_enc, "\n"); SDE_DEBUG_ENC(sde_enc, "\n");
num_encs = sde_enc->num_phys_encs;
mutex_lock(&sde_enc->enc_lock); mutex_lock(&sde_enc->enc_lock);
sde_rsc_client_destroy(sde_enc->rsc_client); 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; struct sde_encoder_phys *phys;
phys = sde_enc->phys_vid_encs[i]; phys = sde_enc->phys_vid_encs[i];
if (phys && phys->ops.destroy) { if (phys && phys->ops.destroy) {
phys->ops.destroy(phys); phys->ops.destroy(phys);
--sde_enc->num_phys_encs; --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]; 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) { if (phys && phys->ops.destroy) {
phys->ops.destroy(phys); phys->ops.destroy(phys);
--sde_enc->num_phys_encs; --sde_enc->num_phys_encs;

View File

@@ -161,8 +161,10 @@ static int _sde_debugfs_init(struct sde_kms *sde_kms)
return 0; 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 */ /* don't need to NULL check debugfs_root */
if (sde_kms) { if (sde_kms) {
sde_debugfs_vbif_destroy(sde_kms); sde_debugfs_vbif_destroy(sde_kms);
@@ -189,7 +191,7 @@ static int _sde_debugfs_init(struct sde_kms *sde_kms)
return 0; 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); _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) { if (sde_kms->catalog) {
for (i = 0; i < sde_kms->catalog->vbif_count; i++) { for (i = 0; i < sde_kms->catalog->vbif_count; i++) {
u32 vbif_idx = sde_kms->catalog->vbif[i].id; 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_kms->mmio = NULL;
sde_reg_dma_deinit(); sde_reg_dma_deinit();
_sde_kms_mmu_destroy(sde_kms);
} }
int sde_kms_mmu_detach(struct sde_kms *sde_kms, bool secure_only) 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_suspend = sde_kms_pm_suspend,
.pm_resume = sde_kms_pm_resume, .pm_resume = sde_kms_pm_resume,
.destroy = sde_kms_destroy, .destroy = sde_kms_destroy,
.debugfs_destroy = sde_kms_debugfs_destroy,
.cont_splash_config = sde_kms_cont_splash_config, .cont_splash_config = sde_kms_cont_splash_config,
.register_events = _sde_kms_register_events, .register_events = _sde_kms_register_events,
.get_address_space = _sde_kms_get_address_space, .get_address_space = _sde_kms_get_address_space,