disp: msm: sde: fix physical encoder spinlock usage
While same spinlock can be used to protect a critical section in both irq-handler and in non-irq context, in non-irq context it is mandatory to use irqsave version of locking api to disable irqs locally on the particular cpu. Otherwise, this could lead to a deadlock if a non-irq thread holding the spinlock and irq handler is scheduled on same cpu. This change replaces physical encoder spinlock locking with irqsave version of locking api in the non-irq context. Change-Id: If73b4c995b75e9499d79fbe969d426427fd3a9d1 Signed-off-by: Prabhanjan Kandula <quic_pkandula@quicinc.com>
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

parent
ace293849c
commit
1fdd965d0b
@@ -213,6 +213,7 @@ void sde_encoder_restore_tearcheck_rd_ptr(struct sde_encoder_phys *phys_enc)
|
|||||||
ktime_t nominal_period_ns, nominal_line_time_ns, panel_scan_line_ts_ns = 0;
|
ktime_t nominal_period_ns, nominal_line_time_ns, panel_scan_line_ts_ns = 0;
|
||||||
ktime_t qsync_period_ns, time_into_frame_ns;
|
ktime_t qsync_period_ns, time_into_frame_ns;
|
||||||
u32 qsync_timeout_lines, latency_margin_lines = 0, restored_rd_ptr_lines;
|
u32 qsync_timeout_lines, latency_margin_lines = 0, restored_rd_ptr_lines;
|
||||||
|
unsigned long flags;
|
||||||
u16 panel_scan_line;
|
u16 panel_scan_line;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@@ -249,7 +250,7 @@ void sde_encoder_restore_tearcheck_rd_ptr(struct sde_encoder_phys *phys_enc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Compensate the latency from DCS scan line response*/
|
/* Compensate the latency from DCS scan line response*/
|
||||||
spin_lock(phys_enc->enc_spinlock);
|
spin_lock_irqsave(phys_enc->enc_spinlock, flags);
|
||||||
sde_encoder_helper_get_pp_line_count(phys_enc->parent, info);
|
sde_encoder_helper_get_pp_line_count(phys_enc->parent, info);
|
||||||
time_into_frame_ns = ktime_sub(ktime_get(), phys_enc->last_vsync_timestamp);
|
time_into_frame_ns = ktime_sub(ktime_get(), phys_enc->last_vsync_timestamp);
|
||||||
|
|
||||||
@@ -263,7 +264,7 @@ void sde_encoder_restore_tearcheck_rd_ptr(struct sde_encoder_phys *phys_enc)
|
|||||||
|
|
||||||
if (hw_intf && hw_intf->ops.override_tear_rd_ptr_val)
|
if (hw_intf && hw_intf->ops.override_tear_rd_ptr_val)
|
||||||
hw_intf->ops.override_tear_rd_ptr_val(hw_intf, restored_rd_ptr_lines);
|
hw_intf->ops.override_tear_rd_ptr_val(hw_intf, restored_rd_ptr_lines);
|
||||||
spin_unlock(phys_enc->enc_spinlock);
|
spin_unlock_irqrestore(phys_enc->enc_spinlock, flags);
|
||||||
|
|
||||||
SDE_EVT32(DRMID(phys_enc->parent), drm_mode_vrefresh(mode),
|
SDE_EVT32(DRMID(phys_enc->parent), drm_mode_vrefresh(mode),
|
||||||
sde_enc->mode_info.qsync_min_fps,
|
sde_enc->mode_info.qsync_min_fps,
|
||||||
@@ -282,6 +283,7 @@ static void _sde_encoder_phys_cmd_setup_sim_qsync_frame(struct sde_encoder_phys
|
|||||||
struct sde_encoder_virt *sde_enc;
|
struct sde_encoder_virt *sde_enc;
|
||||||
struct sde_connector *sde_conn;
|
struct sde_connector *sde_conn;
|
||||||
struct drm_connector *conn;
|
struct drm_connector *conn;
|
||||||
|
unsigned long flags;
|
||||||
u32 qsync_min_fps = 0, nominal_fps = 0, frame_rate = 0;
|
u32 qsync_min_fps = 0, nominal_fps = 0, frame_rate = 0;
|
||||||
u32 nominal_period_us, qsync_min_period_us, time_since_vsync_us;
|
u32 nominal_period_us, qsync_min_period_us, time_since_vsync_us;
|
||||||
int time_before_nominal_vsync_us, time_before_timeout_vsync_us;
|
int time_before_nominal_vsync_us, time_before_timeout_vsync_us;
|
||||||
@@ -301,7 +303,7 @@ static void _sde_encoder_phys_cmd_setup_sim_qsync_frame(struct sde_encoder_phys
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock(phys_enc->enc_spinlock);
|
spin_lock_irqsave(phys_enc->enc_spinlock, flags);
|
||||||
switch (frame) {
|
switch (frame) {
|
||||||
case SDE_SIM_QSYNC_FRAME_NOMINAL:
|
case SDE_SIM_QSYNC_FRAME_NOMINAL:
|
||||||
frame_rate = nominal_fps;
|
frame_rate = nominal_fps;
|
||||||
@@ -358,7 +360,7 @@ static void _sde_encoder_phys_cmd_setup_sim_qsync_frame(struct sde_encoder_phys
|
|||||||
phys_enc->hw_intf->ops.vsync_sel(phys_enc->hw_intf, SDE_VSYNC_SOURCE_WD_TIMER_0);
|
phys_enc->hw_intf->ops.vsync_sel(phys_enc->hw_intf, SDE_VSYNC_SOURCE_WD_TIMER_0);
|
||||||
phys_enc->ops.control_te(phys_enc, true);
|
phys_enc->ops.control_te(phys_enc, true);
|
||||||
phys_enc->sim_qsync_frame = frame;
|
phys_enc->sim_qsync_frame = frame;
|
||||||
spin_unlock(phys_enc->enc_spinlock);
|
spin_unlock_irqrestore(phys_enc->enc_spinlock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _sde_encoder_phys_cmd_process_sim_qsync_event(struct sde_encoder_phys *phys_enc,
|
static void _sde_encoder_phys_cmd_process_sim_qsync_event(struct sde_encoder_phys *phys_enc,
|
||||||
|
Reference in New Issue
Block a user