diff options
| author | Dhaval Patel <pdhaval@codeaurora.org> | 2016-10-25 23:18:48 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-11-01 10:39:22 -0700 |
| commit | 7c8bd9370213d31cb171f16ca37d389ac3aca47f (patch) | |
| tree | 65c188010d50bd056c902831d14e91ea14a52334 | |
| parent | b0dacbac6e24e63422ac524e41c5fee4efd99b66 (diff) | |
drm/msm/sde: fix video encoder access in phy encoder
Video encoder structure member should be accessed
after physical encoder null check. This patch fixes
the current invalid accesses.
Change-Id: Icbd2e5d188a5a3ad459d13a3381325d920cac998
Signed-off-by: Dhaval Patel <pdhaval@codeaurora.org>
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c | 78 |
1 files changed, 49 insertions, 29 deletions
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c index 49712c33a5bc..a4a8626ee91c 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c +++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c @@ -248,22 +248,27 @@ static bool sde_encoder_phys_vid_mode_fixup( static void sde_encoder_phys_vid_setup_timing_engine( struct sde_encoder_phys *phys_enc) { - struct sde_encoder_phys_vid *vid_enc = - to_sde_encoder_phys_vid(phys_enc); - struct drm_display_mode mode = phys_enc->cached_mode; + struct sde_encoder_phys_vid *vid_enc; + struct drm_display_mode mode; struct intf_timing_params timing_params = { 0 }; const struct sde_format *fmt = NULL; u32 fmt_fourcc = DRM_FORMAT_RGB888; unsigned long lock_flags; struct sde_hw_intf_cfg intf_cfg = { 0 }; - if (!phys_enc || - !vid_enc->hw_intf->ops.setup_timing_gen || - !phys_enc->hw_ctl->ops.setup_intf_cfg) { + if (!phys_enc || !phys_enc->hw_ctl || + !phys_enc->hw_ctl->ops.setup_intf_cfg) { SDE_ERROR("invalid encoder %d\n", phys_enc != 0); return; } + mode = phys_enc->cached_mode; + vid_enc = to_sde_encoder_phys_vid(phys_enc); + if (!vid_enc->hw_intf->ops.setup_timing_gen) { + SDE_ERROR("timing engine setup is not supported\n"); + return; + } + SDE_DEBUG_VIDENC(vid_enc, "enabling mode:\n"); drm_mode_debug_printmodeline(&mode); @@ -366,8 +371,7 @@ static int sde_encoder_phys_vid_register_irq(struct sde_encoder_phys *phys_enc, enum sde_intr_type intr_type, int *irq_idx, void (*irq_func)(void *, int), const char *irq_name) { - struct sde_encoder_phys_vid *vid_enc = - to_sde_encoder_phys_vid(phys_enc); + struct sde_encoder_phys_vid *vid_enc; struct sde_irq_callback irq_cb; int ret = 0; @@ -376,6 +380,7 @@ static int sde_encoder_phys_vid_register_irq(struct sde_encoder_phys *phys_enc, return -EINVAL; } + vid_enc = to_sde_encoder_phys_vid(phys_enc); *irq_idx = sde_core_irq_idx_lookup(phys_enc->sde_kms, intr_type, vid_enc->hw_intf->idx); if (*irq_idx < 0) { @@ -417,14 +422,14 @@ static int sde_encoder_phys_vid_register_irq(struct sde_encoder_phys *phys_enc, static int sde_encoder_phys_vid_unregister_irq( struct sde_encoder_phys *phys_enc, int irq_idx) { - struct sde_encoder_phys_vid *vid_enc = - to_sde_encoder_phys_vid(phys_enc); + struct sde_encoder_phys_vid *vid_enc; if (!phys_enc) { SDE_ERROR("invalid encoder\n"); goto end; } + vid_enc = to_sde_encoder_phys_vid(phys_enc); sde_core_irq_disable(phys_enc->sde_kms, &irq_idx, 1); sde_core_irq_register_callback(phys_enc->sde_kms, irq_idx, NULL); @@ -440,17 +445,17 @@ static void sde_encoder_phys_vid_mode_set( struct drm_display_mode *mode, struct drm_display_mode *adj_mode) { - struct sde_encoder_phys_vid *vid_enc = - to_sde_encoder_phys_vid(phys_enc); struct sde_rm *rm = &phys_enc->sde_kms->rm; struct sde_rm_hw_iter iter; int i, instance; + struct sde_encoder_phys_vid *vid_enc; if (!phys_enc) { SDE_ERROR("invalid encoder\n"); return; } + vid_enc = to_sde_encoder_phys_vid(phys_enc); phys_enc->cached_mode = *adj_mode; SDE_DEBUG_VIDENC(vid_enc, "caching mode:\n"); drm_mode_debug_printmodeline(adj_mode); @@ -477,15 +482,16 @@ static int sde_encoder_phys_vid_control_vblank_irq( struct sde_encoder_phys *phys_enc, bool enable) { - struct sde_encoder_phys_vid *vid_enc = - to_sde_encoder_phys_vid(phys_enc); int ret = 0; + struct sde_encoder_phys_vid *vid_enc; if (!phys_enc) { SDE_ERROR("invalid encoder\n"); return -EINVAL; } + vid_enc = to_sde_encoder_phys_vid(phys_enc); + /* Slave encoders don't report vblank */ if (!sde_encoder_phys_vid_is_master(phys_enc)) return 0; @@ -516,17 +522,21 @@ static int sde_encoder_phys_vid_control_vblank_irq( static void sde_encoder_phys_vid_enable(struct sde_encoder_phys *phys_enc) { - struct sde_encoder_phys_vid *vid_enc = - to_sde_encoder_phys_vid(phys_enc); - struct sde_hw_intf *intf = vid_enc->hw_intf; - struct sde_hw_ctl *ctl = phys_enc->hw_ctl; + struct sde_encoder_phys_vid *vid_enc; + struct sde_hw_intf *intf; + struct sde_hw_ctl *ctl; u32 flush_mask = 0; int ret; if (!phys_enc) { SDE_ERROR("invalid encoder\n"); return; - } else if (!vid_enc->hw_intf || !phys_enc->hw_ctl) { + } + + vid_enc = to_sde_encoder_phys_vid(phys_enc); + intf = vid_enc->hw_intf; + ctl = phys_enc->hw_ctl; + if (!vid_enc->hw_intf || !phys_enc->hw_ctl) { SDE_ERROR("invalid hw_intf %d hw_ctl %d\n", vid_enc->hw_intf != 0, phys_enc->hw_ctl != 0); return; @@ -573,13 +583,15 @@ end: static void sde_encoder_phys_vid_disable(struct sde_encoder_phys *phys_enc) { unsigned long lock_flags; - struct sde_encoder_phys_vid *vid_enc = - to_sde_encoder_phys_vid(phys_enc); + struct sde_encoder_phys_vid *vid_enc; if (!phys_enc) { SDE_ERROR("invalid encoder\n"); return; - } else if (!vid_enc->hw_intf || !phys_enc->hw_ctl) { + } + + vid_enc = to_sde_encoder_phys_vid(phys_enc); + if (!vid_enc->hw_intf || !phys_enc->hw_ctl) { SDE_ERROR("invalid hw_intf %d hw_ctl %d\n", vid_enc->hw_intf != 0, phys_enc->hw_ctl != 0); return; @@ -623,13 +635,14 @@ static void sde_encoder_phys_vid_disable(struct sde_encoder_phys *phys_enc) static void sde_encoder_phys_vid_destroy(struct sde_encoder_phys *phys_enc) { - struct sde_encoder_phys_vid *vid_enc = - to_sde_encoder_phys_vid(phys_enc); + struct sde_encoder_phys_vid *vid_enc; if (!phys_enc) { SDE_ERROR("invalid encoder\n"); return; } + + vid_enc = to_sde_encoder_phys_vid(phys_enc); SDE_DEBUG_VIDENC(vid_enc, "\n"); kfree(vid_enc); } @@ -639,14 +652,20 @@ static void sde_encoder_phys_vid_get_hw_resources( struct sde_encoder_hw_resources *hw_res, struct drm_connector_state *conn_state) { - struct sde_encoder_phys_vid *vid_enc = - to_sde_encoder_phys_vid(phys_enc); + struct sde_encoder_phys_vid *vid_enc; - if (!phys_enc || !hw_res || !vid_enc->hw_intf) { + if (!phys_enc || !hw_res) { SDE_ERROR("invalid arg(s), enc %d hw_res %d conn_state %d\n", phys_enc != 0, hw_res != 0, conn_state != 0); return; } + + vid_enc = to_sde_encoder_phys_vid(phys_enc); + if (!vid_enc->hw_intf) { + SDE_ERROR("invalid arg(s), hw_intf\n"); + return; + } + SDE_DEBUG_VIDENC(vid_enc, "\n"); hw_res->intfs[vid_enc->hw_intf->idx - INTF_0] = INTF_MODE_VIDEO; } @@ -700,13 +719,14 @@ static void sde_encoder_phys_vid_handle_post_kickoff( struct sde_encoder_phys *phys_enc) { unsigned long lock_flags; - struct sde_encoder_phys_vid *vid_enc = - to_sde_encoder_phys_vid(phys_enc); + struct sde_encoder_phys_vid *vid_enc; if (!phys_enc) { SDE_ERROR("invalid encoder\n"); return; } + + vid_enc = to_sde_encoder_phys_vid(phys_enc); SDE_DEBUG_VIDENC(vid_enc, "enable_state %d\n", phys_enc->enable_state); /* |
