Commit 98fbe6bb authored by Dmitry Baryshkov's avatar Dmitry Baryshkov Committed by Rob Clark

drm/msm/dpu: hw_intr: always call dpu_hw_intr_clear_intr_status_nolock

Always call dpu_hw_intr_clear_intr_status_nolock() from the
dpu_hw_intr_dispatch_irqs(). This simplifies the callback function
(which call clears the interrupts anyway) and enforces clearing the hw
interrupt status.
Signed-off-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
Reviewed-by: default avatarAbhinav Kumar <abhinavk@codeaurora.org>
Link: https://lore.kernel.org/r/20210516202910.2141079-3-dmitry.baryshkov@linaro.orgSigned-off-by: default avatarRob Clark <robdclark@chromium.org>
parent 09e3a2b4
......@@ -41,15 +41,6 @@ static void dpu_core_irq_callback_handler(void *arg, int irq_idx)
if (cb->func)
cb->func(cb->arg, irq_idx);
spin_unlock_irqrestore(&dpu_kms->irq_obj.cb_lock, irq_flags);
/*
* Clear pending interrupt status in HW.
* NOTE: dpu_core_irq_callback_handler is protected by top-level
* spinlock, so it is safe to clear any interrupt status here.
*/
dpu_kms->hw_intr->ops.clear_intr_status_nolock(
dpu_kms->hw_intr,
irq_idx);
}
int dpu_core_irq_idx_lookup(struct dpu_kms *dpu_kms,
......
......@@ -1362,6 +1362,22 @@ static int dpu_hw_intr_irqidx_lookup(struct dpu_hw_intr *intr,
return -EINVAL;
}
static void dpu_hw_intr_clear_intr_status_nolock(struct dpu_hw_intr *intr,
int irq_idx)
{
int reg_idx;
if (!intr)
return;
reg_idx = dpu_irq_map[irq_idx].reg_idx;
DPU_REG_WRITE(&intr->hw, dpu_intr_set[reg_idx].clr_off,
dpu_irq_map[irq_idx].irq_mask);
/* ensure register writes go through */
wmb();
}
static void dpu_hw_intr_dispatch_irq(struct dpu_hw_intr *intr,
void (*cbfunc)(void *, int),
void *arg)
......@@ -1430,9 +1446,8 @@ static void dpu_hw_intr_dispatch_irq(struct dpu_hw_intr *intr,
*/
if (cbfunc)
cbfunc(arg, irq_idx);
else
intr->ops.clear_intr_status_nolock(
intr, irq_idx);
dpu_hw_intr_clear_intr_status_nolock(intr, irq_idx);
/*
* When callback finish, clear the irq_status
......@@ -1597,23 +1612,6 @@ static int dpu_hw_intr_disable_irqs(struct dpu_hw_intr *intr)
return 0;
}
static void dpu_hw_intr_clear_intr_status_nolock(struct dpu_hw_intr *intr,
int irq_idx)
{
int reg_idx;
if (!intr)
return;
reg_idx = dpu_irq_map[irq_idx].reg_idx;
DPU_REG_WRITE(&intr->hw, dpu_intr_set[reg_idx].clr_off,
dpu_irq_map[irq_idx].irq_mask);
/* ensure register writes go through */
wmb();
}
static u32 dpu_hw_intr_get_interrupt_status(struct dpu_hw_intr *intr,
int irq_idx, bool clear)
{
......@@ -1655,7 +1653,6 @@ static void __setup_intr_ops(struct dpu_hw_intr_ops *ops)
ops->dispatch_irqs = dpu_hw_intr_dispatch_irq;
ops->clear_all_irqs = dpu_hw_intr_clear_irqs;
ops->disable_all_irqs = dpu_hw_intr_disable_irqs;
ops->clear_intr_status_nolock = dpu_hw_intr_clear_intr_status_nolock;
ops->get_interrupt_status = dpu_hw_intr_get_interrupt_status;
}
......
......@@ -142,15 +142,6 @@ struct dpu_hw_intr_ops {
void (*cbfunc)(void *arg, int irq_idx),
void *arg);
/**
* clear_intr_status_nolock() - clears the HW interrupts without lock
* @intr: HW interrupt handle
* @irq_idx: Lookup irq index return from irq_idx_lookup
*/
void (*clear_intr_status_nolock)(
struct dpu_hw_intr *intr,
int irq_idx);
/**
* get_interrupt_status - Gets HW interrupt status, and clear if set,
* based on given lookup IRQ index.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment