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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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;
|
||||||
|
@@ -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,
|
||||||
|
Reference in New Issue
Block a user