summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorraghavendra ambadas <rambad@codeaurora.org>2020-03-27 14:04:04 +0530
committerraghavendra ambadas <rambad@codeaurora.org>2020-03-30 16:49:35 +0530
commit7bf181eab7afce1d1af1d7cb60ffe172b13bfffe (patch)
tree53306465b50db540e6d51d6c0457c46cbcdf96b7
parent6aa80572375c0b938e99f7da9cd45a2887a1293c (diff)
fbdev: msm: handle unbalanced TE irq calls
Due to TE irq enabled/disabled from both dsi blank/unblank and from the wait4pingpong function during esd panel recovery, which causes unbalanced te irq calls during enabling, this fails panel recovery fail during esd test. Fix the issue by synchronizing the irq calls using single function call to update the te irq from different functions. Change-Id: Ia7a532f28f6ecc1c509406ca1dbc129fcd8a9244 Signed-off-by: Raghavendra Ambadas <rambad@codeaurora.org>
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi.c9
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c9
-rw-r--r--drivers/video/fbdev/msm/mdss_panel.h21
3 files changed, 29 insertions, 10 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c
index c2cfc8e0532e..cc5f21131809 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.c
+++ b/drivers/video/fbdev/msm/mdss_dsi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1704,7 +1704,7 @@ static int mdss_dsi_unblank(struct mdss_panel_data *pdata)
mipi->vsync_enable && mipi->hw_vsync_mode) {
mdss_dsi_set_tear_on(ctrl_pdata);
if (mdss_dsi_is_te_based_esd(ctrl_pdata))
- enable_irq(gpio_to_irq(ctrl_pdata->disp_te_gpio));
+ panel_update_te_irq(pdata, true);
}
ctrl_pdata->ctrl_state |= CTRL_STATE_PANEL_INIT;
@@ -1775,9 +1775,8 @@ static int mdss_dsi_blank(struct mdss_panel_data *pdata, int power_state)
if ((pdata->panel_info.type == MIPI_CMD_PANEL) &&
mipi->vsync_enable && mipi->hw_vsync_mode) {
if (mdss_dsi_is_te_based_esd(ctrl_pdata)) {
- disable_irq(gpio_to_irq(
- ctrl_pdata->disp_te_gpio));
- atomic_dec(&ctrl_pdata->te_irq_ready);
+ panel_update_te_irq(pdata, false);
+ atomic_dec(&ctrl_pdata->te_irq_ready);
}
mdss_dsi_set_tear_off(ctrl_pdata);
}
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
index 83ab9c3973af..b46e955f280b 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2018, 2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -2099,7 +2099,7 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg)
struct mdss_mdp_cmd_ctx *ctx;
struct mdss_panel_data *pdata;
unsigned long flags;
- int rc = 0, te_irq;
+ int rc = 0;
ctx = (struct mdss_mdp_cmd_ctx *) ctl->intf_ctx[MASTER_CTX];
if (!ctx) {
@@ -2155,8 +2155,7 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg)
atomic_read(&ctx->koff_cnt));
/* enable TE irq to check if it is coming from the panel */
- te_irq = gpio_to_irq(pdata->panel_te_gpio);
- enable_irq(te_irq);
+ panel_update_te_irq(pdata, true);
/* wait for 20ms to ensure we are getting the next TE */
usleep_range(20000, 20010);
@@ -2179,7 +2178,7 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg)
}
/* disable te irq */
- disable_irq_nosync(te_irq);
+ panel_update_te_irq(pdata, false);
ctx->pp_timeout_report_cnt++;
rc = -EPERM;
diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h
index 1e0ae618b501..200acc5e61aa 100644
--- a/drivers/video/fbdev/msm/mdss_panel.h
+++ b/drivers/video/fbdev/msm/mdss_panel.h
@@ -19,6 +19,9 @@
#include <linux/stringify.h>
#include <linux/types.h>
#include <linux/debugfs.h>
+#include <linux/of_gpio.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
/* panel id type */
struct panel_id {
@@ -1010,6 +1013,7 @@ struct mdss_panel_data {
bool panel_disable_mode;
int panel_te_gpio;
+ bool is_te_irq_enabled;
struct completion te_done;
};
@@ -1021,6 +1025,23 @@ struct mdss_panel_debugfs_info {
struct mdss_panel_debugfs_info *next;
};
+static inline void panel_update_te_irq(struct mdss_panel_data *pdata,
+ bool enable)
+{
+ if (!pdata) {
+ pr_err("Invalid Params\n");
+ return;
+ }
+
+ if (enable && !pdata->is_te_irq_enabled) {
+ enable_irq(gpio_to_irq(pdata->panel_te_gpio));
+ pdata->is_te_irq_enabled = true;
+ } else if (!enable && pdata->is_te_irq_enabled) {
+ disable_irq(gpio_to_irq(pdata->panel_te_gpio));
+ pdata->is_te_irq_enabled = false;
+ }
+}
+
/**
* mdss_get_panel_framerate() - get panel frame rate based on panel information
* @panel_info: Pointer to panel info containing all panel information