diff options
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dp.c | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c index a74bf6f60774..3758c4bdac7f 100644 --- a/drivers/video/fbdev/msm/mdss_dp.c +++ b/drivers/video/fbdev/msm/mdss_dp.c @@ -1674,6 +1674,8 @@ exit: int mdss_dp_on(struct mdss_panel_data *pdata) { struct mdss_dp_drv_pdata *dp_drv = NULL; + bool hpd; + int rc = 0; if (!pdata) { pr_err("Invalid input data\n"); @@ -1683,6 +1685,22 @@ int mdss_dp_on(struct mdss_panel_data *pdata) dp_drv = container_of(pdata, struct mdss_dp_drv_pdata, panel_data); + mutex_lock(&dp_drv->attention_lock); + hpd = dp_drv->cable_connected; + mutex_unlock(&dp_drv->attention_lock); + + /* In case of device coming out of PM_SUSPEND, there can be + * a corner case where the sink is turned off or the DP cable + * is disconnected almost at the same time as userspace triggering + * unblank. This can cause the UNBLANK call to be still triggered + * before the disconnect event is notified to the userspace. + * Avoid turning ON DP path in such cases. + */ + if (!hpd || !dp_drv->alt_mode.dp_status.hpd_high) { + pr_err("DP sink not connected\n"); + return -EINVAL; + } + /* * If the link already active, then nothing needs to be done here. * However, it is possible that the the power_on flag could be @@ -1707,8 +1725,11 @@ int mdss_dp_on(struct mdss_panel_data *pdata) * init/deinit during unrelated resume/suspend events, * add host initialization call before DP power-on. */ - if (!dp_drv->dp_initialized) - mdss_dp_host_init(pdata); + if (!dp_drv->dp_initialized) { + rc = mdss_dp_host_init(pdata); + if (rc < 0) + return rc; + } return mdss_dp_on_hpd(dp_drv); } @@ -1941,6 +1962,11 @@ static int mdss_dp_host_init(struct mdss_panel_data *pdata) } dp_drv->orientation = usbpd_get_plug_orientation(dp_drv->pd); + if (dp_drv->orientation == ORIENTATION_NONE) { + pr_err("DP cable might be disconnected\n"); + ret = -EINVAL; + goto orientation_error; + } dp_drv->aux_sel_gpio_output = 0; if (dp_drv->orientation == ORIENTATION_CC2) @@ -1981,8 +2007,9 @@ static int mdss_dp_host_init(struct mdss_panel_data *pdata) return 0; clk_error: - mdss_dp_regulator_ctrl(dp_drv, false); mdss_dp_config_gpios(dp_drv, false); +orientation_error: + mdss_dp_regulator_ctrl(dp_drv, false); vreg_error: return ret; } |
