diff --git a/msm/dsi/dsi_ctrl.c b/msm/dsi/dsi_ctrl.c index 5274d4e427..35e90f1e3b 100644 --- a/msm/dsi/dsi_ctrl.c +++ b/msm/dsi/dsi_ctrl.c @@ -17,6 +17,7 @@ #include "dsi_ctrl.h" #include "dsi_ctrl_hw.h" #include "dsi_clk.h" +#include "dsi_display.h" #include "dsi_pwr.h" #include "dsi_catalog.h" #include "dsi_panel.h" @@ -2717,6 +2718,8 @@ static void dsi_ctrl_handle_error_status(struct dsi_ctrl *dsi_ctrl, unsigned long error) { struct dsi_event_cb_info cb_info; + struct dsi_display *display; + bool skip_irq_enable = false; cb_info = dsi_ctrl->irq_info.irq_err_cb; @@ -2766,6 +2769,9 @@ static void dsi_ctrl_handle_error_status(struct dsi_ctrl *dsi_ctrl, cb_info.event_idx, dsi_ctrl->cell_index, 0, 0, 0, 0); + display = cb_info.event_usr_ptr; + dsi_display_report_dead(display); + skip_irq_enable = true; } } @@ -2777,6 +2783,9 @@ static void dsi_ctrl_handle_error_status(struct dsi_ctrl *dsi_ctrl, cb_info.event_idx, dsi_ctrl->cell_index, 0, 0, 0, 0); + display = cb_info.event_usr_ptr; + dsi_display_report_dead(display); + skip_irq_enable = true; } } @@ -2802,7 +2811,7 @@ static void dsi_ctrl_handle_error_status(struct dsi_ctrl *dsi_ctrl, } /* enable back DSI interrupts */ - if (dsi_ctrl->hw.ops.error_intr_ctrl) + if (dsi_ctrl->hw.ops.error_intr_ctrl && !skip_irq_enable) dsi_ctrl->hw.ops.error_intr_ctrl(&dsi_ctrl->hw, true); } diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index d73c61c19f..84480e3f52 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -9131,6 +9131,16 @@ int dsi_display_unprepare(struct dsi_display *display) return rc; } +void dsi_display_report_dead(struct dsi_display *display) +{ + struct sde_connector *c_conn = to_sde_connector(display->drm_conn); + + /* disable work queue */ + sde_connector_schedule_status_work(display->drm_conn, false); + + sde_connector_report_panel_dead(c_conn, false); +} + void __init dsi_display_register(void) { dsi_phy_drv_register(); diff --git a/msm/dsi/dsi_display.h b/msm/dsi/dsi_display.h index e19c2a8393..89ce2e9ad9 100644 --- a/msm/dsi/dsi_display.h +++ b/msm/dsi/dsi_display.h @@ -848,4 +848,11 @@ int dsi_display_update_transfer_time(void *display, u32 transfer_time); */ int dsi_display_get_panel_scan_line(void *display, u16 *scan_line, ktime_t *scan_line_ts); +/** + * dsi_display_report_dead() - report panel dead and cancel work queue + * @display: handle to display + * + */ +void dsi_display_report_dead(struct dsi_display *display); + #endif /* _DSI_DISPLAY_H_ */ diff --git a/msm/sde/sde_connector.c b/msm/sde/sde_connector.c index 29d29d1f7c..25981fc820 100644 --- a/msm/sde/sde_connector.c +++ b/msm/sde/sde_connector.c @@ -2784,7 +2784,7 @@ static int sde_connector_atomic_check(struct drm_connector *connector, return 0; } -static void _sde_connector_report_panel_dead(struct sde_connector *conn, +void sde_connector_report_panel_dead(struct sde_connector *conn, bool skip_pre_kickoff) { struct drm_event event; @@ -2865,7 +2865,7 @@ int sde_connector_esd_status(struct drm_connector *conn) if (ret <= 0) { /* cancel if any pending esd work */ sde_connector_schedule_status_work(conn, false); - _sde_connector_report_panel_dead(sde_conn, true); + sde_connector_report_panel_dead(sde_conn, true); ret = -ETIMEDOUT; } else { SDE_DEBUG("Successfully received TE from panel\n"); @@ -2916,7 +2916,7 @@ static void sde_connector_check_status_work(struct work_struct *work) return; } - _sde_connector_report_panel_dead(conn, false); + sde_connector_report_panel_dead(conn, false); } static const struct drm_connector_helper_funcs sde_connector_helper_ops = { diff --git a/msm/sde/sde_connector.h b/msm/sde/sde_connector.h index 8e5c55bf79..e40003e8ad 100644 --- a/msm/sde/sde_connector.h +++ b/msm/sde/sde_connector.h @@ -1386,4 +1386,11 @@ const char *sde_conn_get_topology_name(struct drm_connector *conn, */ bool sde_connector_is_line_insertion_supported(struct sde_connector *sde_conn); +/* + * sde_connector_report_panel_dead - report panel dead notification + * @sde_conn: Pointer to sde connector structure + * @skip_pre_kickoff: boolean to skip pre kickoff + */ +void sde_connector_report_panel_dead(struct sde_connector *conn, bool skip_pre_kickoff); + #endif /* _SDE_CONNECTOR_H_ */