From aab8bf69cbfcf925624c8fcd855ce13116d90d50 Mon Sep 17 00:00:00 2001 From: Prashant Singh Date: Wed, 18 Sep 2019 02:26:45 +0530 Subject: [PATCH] msm/sde: prevent double register of input handler During Dynamic mode switch case, input_register_handler is called even after it is registered leading to list double add warnings and panic. Change-Id: I312112deb08c998af516252f2117bc629eb13b37 --- techpack/display/msm/sde/sde_encoder.c | 37 ++++++++++++++------------ 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/techpack/display/msm/sde/sde_encoder.c b/techpack/display/msm/sde/sde_encoder.c index 5bd0bbdc9da4..cbb8b5b87bbc 100644 --- a/techpack/display/msm/sde/sde_encoder.c +++ b/techpack/display/msm/sde/sde_encoder.c @@ -285,6 +285,7 @@ struct sde_encoder_virt { struct kthread_work input_event_work; struct kthread_work esd_trigger_work; struct input_handler *input_handler; + bool input_handler_registered; struct msm_display_topology topology; bool vblank_enabled; bool idle_pc_restore; @@ -772,6 +773,7 @@ void sde_encoder_destroy(struct drm_encoder *drm_enc) kfree(sde_enc->input_handler); sde_enc->input_handler = NULL; + sde_enc->input_handler_registered = false; kfree(sde_enc); } @@ -3204,21 +3206,6 @@ static void _sde_encoder_input_handler_register( } } -static void _sde_encoder_input_handler_unregister( - struct drm_encoder *drm_enc) -{ - struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc); - - if (!sde_encoder_check_curr_mode(drm_enc, MSM_DISPLAY_CMD_MODE)) - return; - - if (sde_enc->input_handler && sde_enc->input_handler->private) { - input_unregister_handler(sde_enc->input_handler); - sde_enc->input_handler->private = NULL; - } - -} - static int _sde_encoder_input_handler( struct sde_encoder_virt *sde_enc) { @@ -3242,6 +3229,7 @@ static int _sde_encoder_input_handler( input_handler->id_table = sde_input_ids; sde_enc->input_handler = input_handler; + sde_enc->input_handler_registered = false; return rc; } @@ -3398,7 +3386,18 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc) return; } - _sde_encoder_input_handler_register(drm_enc); + /* register input handler if not already registered */ + if (sde_enc->input_handler && !sde_enc->input_handler_registered && + !msm_is_mode_seamless_dms(cur_mode) && + sde_encoder_check_curr_mode(drm_enc, MSM_DISPLAY_CMD_MODE) && + !msm_is_mode_seamless_dyn_clk(cur_mode)) { + _sde_encoder_input_handler_register(drm_enc); + if (!sde_enc->input_handler || !sde_enc->input_handler->private) + SDE_ERROR( + "input handler registration failed, rc = %d\n", ret); + else + sde_enc->input_handler_registered = true; + } if ((drm_enc->crtc && drm_enc->crtc->state && drm_enc->crtc->state->connectors_changed && @@ -3529,7 +3528,11 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) if (!sde_encoder_in_clone_mode(drm_enc)) sde_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE); - _sde_encoder_input_handler_unregister(drm_enc); + if (sde_enc->input_handler && sde_enc->input_handler_registered && + sde_encoder_check_curr_mode(drm_enc, MSM_DISPLAY_CMD_MODE)) { + input_unregister_handler(sde_enc->input_handler); + sde_enc->input_handler_registered = false; + } /* * For primary command mode and video mode encoders, execute the