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: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Reviewed-by: Abhinav Kumar <abhinavk@codeaurora.org>
Link: https://lore.kernel.org/r/20210516202910.2141079-3-dmitry.baryshkov@linaro.org
Signed-off-by: Rob Clark <robdclark@chromium.org>
This commit is contained in:
Dmitry Baryshkov 2021-05-16 23:29:07 +03:00 committed by Rob Clark
parent 09e3a2b442
commit 98fbe6bb5b
3 changed files with 18 additions and 39 deletions

View File

@ -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,

View File

@ -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;
}

View File

@ -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.