summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDhaval Patel <pdhaval@codeaurora.org>2016-10-25 23:18:48 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-11-01 10:39:22 -0700
commit7c8bd9370213d31cb171f16ca37d389ac3aca47f (patch)
tree65c188010d50bd056c902831d14e91ea14a52334
parentb0dacbac6e24e63422ac524e41c5fee4efd99b66 (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.c78
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);
/*