From 5fbf460eef1fecd419509bcaa5a48f39aa3ea3e0 Mon Sep 17 00:00:00 2001 From: Navneet Kumar Date: Tue, 28 Mar 2017 13:50:43 -0700 Subject: tegra: dc: fix fake panel state machine data In fake panel support, the state machine caches dc contexts in a 2D array. This exposes a bug if a test switches between fake modes sequentially without falling back to original (non fake) mode before switching to the next fake mode. In the above scenario, coming back to the original mode (non fake) may lead to finding no cached dc context, hence causing a crash. go back to the old way of doing this, and have a 1D array to cache the contexts, getting rid of the unnecessary logic/compexity from 2D array. Bug 1883138 Change-Id: Ia3521b56b801cf00b0cc7e34047f40c8655f2cdd Signed-off-by: Navneet Kumar Reviewed-on: http://git-master/r/1330141 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/video/tegra/dc/dc.c | 51 ++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c index 91fc96bb2..52508a9bd 100644 --- a/drivers/video/tegra/dc/dc.c +++ b/drivers/video/tegra/dc/dc.c @@ -1160,8 +1160,8 @@ struct tegra_dc_out_info { struct tegra_edid *edid; }; -static struct tegra_dc_out_info dbg_dc_out_info[TEGRA_DC_OUT_MAX] - [TEGRA_DC_OUT_MAX]; +static struct tegra_dc_out_info dbg_dc_out_info[TEGRA_DC_OUT_MAX]; + /* array for saving the out_type for each head */ static int boot_out_type[] = {-1, -1, -1}; @@ -1216,7 +1216,7 @@ static int set_avdd(struct tegra_dc *dc, long cur_out, long new_out) */ bool is_enable = false; struct tegra_dc_out *dc_out = - &dbg_dc_out_info[boot_out_type[dc->ndev->id]][new_out].out; + &dbg_dc_out_info[boot_out_type[dc->ndev->id]].out; /* cur is fake and new is fake - skip */ if (is_valid_fake_support(dc, cur_out) && @@ -1288,37 +1288,37 @@ static ssize_t dbg_dc_out_type_set(struct file *file, /* If output is already created - save it */ if (dc->out_data) { - dbg_dc_out_info[cur_dc_out][out_type].out_data = dc->out_data; - dbg_dc_out_info[cur_dc_out][out_type].out_ops = dc->out_ops; - memcpy(&dbg_dc_out_info[cur_dc_out][out_type].out, dc->out, + dbg_dc_out_info[cur_dc_out].out_data = dc->out_data; + dbg_dc_out_info[cur_dc_out].out_ops = dc->out_ops; + memcpy(&dbg_dc_out_info[cur_dc_out].out, dc->out, sizeof(struct tegra_dc_out)); - dbg_dc_out_info[cur_dc_out][out_type].mode = dc->mode; - dbg_dc_out_info[cur_dc_out][out_type].edid = dc->edid; + dbg_dc_out_info[cur_dc_out].mode = dc->mode; + dbg_dc_out_info[cur_dc_out].edid = dc->edid; if (is_valid_dsi_out(dc, cur_dc_out) && - dbg_dc_out_info[cur_dc_out][out_type].out_data) + dbg_dc_out_info[cur_dc_out].out_data) tegra_dc_destroy_dsi_resources(dc, cur_dc_out); if (!is_valid_fake_support(dc, cur_dc_out)) - dbg_dc_out_info[cur_dc_out][out_type].fblistindex = + dbg_dc_out_info[cur_dc_out].fblistindex = tegra_fb_update_modelist(dc, 0); set_avdd(dc, cur_dc_out, out_type); } /* If output already created - reuse it */ - if (dbg_dc_out_info[out_type][cur_dc_out].out_data) { + if (dbg_dc_out_info[out_type].out_data) { mutex_lock(&dc->lp_lock); mutex_lock(&dc->lock); /* Change the out type */ dc->pdata->default_out->type = out_type; - dc->out_ops = dbg_dc_out_info[out_type][cur_dc_out].out_ops; - dc->out_data = dbg_dc_out_info[out_type][cur_dc_out].out_data; - memcpy(dc->out, &dbg_dc_out_info[out_type][cur_dc_out].out, + dc->out_ops = dbg_dc_out_info[out_type].out_ops; + dc->out_data = dbg_dc_out_info[out_type].out_data; + memcpy(dc->out, &dbg_dc_out_info[out_type].out, sizeof(struct tegra_dc_out)); - dc->mode = dbg_dc_out_info[out_type][cur_dc_out].mode; - dc->edid = dbg_dc_out_info[out_type][cur_dc_out].edid; + dc->mode = dbg_dc_out_info[out_type].mode; + dc->edid = dbg_dc_out_info[out_type].edid; /* Re-init the resources that are destroyed for dsi */ if (is_valid_dsi_out(dc, out_type)) @@ -1326,8 +1326,7 @@ static ssize_t dbg_dc_out_type_set(struct file *file, if (!is_valid_fake_support(dc, out_type)) tegra_fb_update_modelist(dc, - dbg_dc_out_info[out_type] - [cur_dc_out].fblistindex); + dbg_dc_out_info[out_type].fblistindex); mutex_unlock(&dc->lock); mutex_unlock(&dc->lp_lock); @@ -1370,15 +1369,15 @@ static ssize_t dbg_dc_out_type_set(struct file *file, tegra_dc_init_fakedsi_panel(dc, out_type); } else if (out_type == TEGRA_DC_OUT_NULL) { - if (!dbg_dc_out_info[TEGRA_DC_OUT_NULL] - [cur_dc_out].out_data) { + if (!dbg_dc_out_info[TEGRA_DC_OUT_NULL].out_data) { allocate = true; tegra_dc_init_null_or(dc); } } else { /* set back to existing one */ dc->pdata->default_out->type = cur_dc_out; - dev_err(&dc->ndev->dev, "Unknown type is asked\n"); + dev_err(&dc->ndev->dev, "Unknown type is asked: %ld\n", + out_type); goto by_pass; } @@ -1391,12 +1390,12 @@ static ssize_t dbg_dc_out_type_set(struct file *file, } } - dbg_dc_out_info[out_type][cur_dc_out].out_ops = dc->out_ops; - dbg_dc_out_info[out_type][cur_dc_out].out_data = dc->out_data; - memcpy(&dbg_dc_out_info[out_type][cur_dc_out].out, dc->out, + dbg_dc_out_info[out_type].out_ops = dc->out_ops; + dbg_dc_out_info[out_type].out_data = dc->out_data; + memcpy(&dbg_dc_out_info[out_type].out, dc->out, sizeof(struct tegra_dc_out)); - dbg_dc_out_info[out_type][cur_dc_out].mode = dc->mode; - dbg_dc_out_info[out_type][cur_dc_out].edid = dc->edid; + dbg_dc_out_info[out_type].mode = dc->mode; + dbg_dc_out_info[out_type].edid = dc->edid; } -- cgit v1.2.2