aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/sde/sde_hw_interrupts.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/msm/sde/sde_hw_interrupts.c')
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_interrupts.c70
1 files changed, 15 insertions, 55 deletions
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_interrupts.c b/drivers/gpu/drm/msm/sde/sde_hw_interrupts.c
index 0fc778e35f88..038b1fc53907 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_interrupts.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_interrupts.c
@@ -886,8 +886,6 @@ static void sde_hw_intr_dispatch_irq(struct sde_hw_intr *intr,
*/
spin_lock_irqsave(&intr->irq_lock, irq_flags);
for (reg_idx = 0; reg_idx < intr->sde_irq_size; reg_idx++) {
- irq_status = intr->save_irq_status[reg_idx];
-
/* get the global offset in 'sde_irq_map' */
sde_irq_idx = intr->sde_irq_tbl[reg_idx].sde_irq_idx;
if (sde_irq_idx < 0)
@@ -904,6 +902,9 @@ static void sde_hw_intr_dispatch_irq(struct sde_hw_intr *intr,
end_idx > ARRAY_SIZE(sde_irq_map))
continue;
+ irq_status = SDE_REG_READ(&intr->hw,
+ intr->sde_irq_tbl[reg_idx].status_off);
+
/*
* Search through matching intr status from irq map.
* start_idx and end_idx defined the search range in
@@ -924,8 +925,9 @@ static void sde_hw_intr_dispatch_irq(struct sde_hw_intr *intr,
if (cbfunc)
cbfunc(arg, irq_idx);
else
- intr->ops.clear_intr_status_nolock(
- intr, irq_idx);
+ SDE_REG_WRITE(&intr->hw,
+ intr->sde_irq_tbl[reg_idx].clr_off,
+ sde_irq_map[irq_idx].irq_mask);
/*
* When callback finish, clear the irq_status
@@ -977,9 +979,6 @@ static int sde_hw_intr_enable_irq(struct sde_hw_intr *intr, int irq_idx)
/* Enabling interrupts with the new mask */
SDE_REG_WRITE(&intr->hw, reg->en_off, cache_irq_mask);
- /* ensure register write goes through */
- wmb();
-
intr->cache_irq_mask[reg_idx] = cache_irq_mask;
}
spin_unlock_irqrestore(&intr->irq_lock, irq_flags);
@@ -1115,40 +1114,6 @@ static int sde_hw_intr_get_interrupt_sources(struct sde_hw_intr *intr,
return 0;
}
-static void sde_hw_intr_get_interrupt_statuses(struct sde_hw_intr *intr)
-{
- int i;
- u32 enable_mask;
- unsigned long irq_flags;
-
- if (!intr)
- return;
-
- spin_lock_irqsave(&intr->irq_lock, irq_flags);
- for (i = 0; i < intr->sde_irq_size; i++) {
- /* Read interrupt status */
- intr->save_irq_status[i] = SDE_REG_READ(&intr->hw,
- intr->sde_irq_tbl[i].status_off);
-
- /* Read enable mask */
- enable_mask = SDE_REG_READ(&intr->hw,
- intr->sde_irq_tbl[i].en_off);
-
- /* and clear the interrupt */
- if (intr->save_irq_status[i])
- SDE_REG_WRITE(&intr->hw, intr->sde_irq_tbl[i].clr_off,
- intr->save_irq_status[i]);
-
- /* Finally update IRQ status based on enable mask */
- intr->save_irq_status[i] &= enable_mask;
- }
-
- /* ensure register writes go through */
- wmb();
-
- spin_unlock_irqrestore(&intr->irq_lock, irq_flags);
-}
-
static void sde_hw_intr_clear_intr_status_force_mask(struct sde_hw_intr *intr,
int irq_idx, u32 irq_mask)
{
@@ -1200,12 +1165,20 @@ static void sde_hw_intr_clear_interrupt_status(struct sde_hw_intr *intr,
int irq_idx)
{
unsigned long irq_flags;
+ int reg_idx;
if (!intr)
return;
+ reg_idx = sde_irq_map[irq_idx].reg_idx;
+ if (reg_idx < 0 || reg_idx > intr->sde_irq_size) {
+ pr_err("invalid irq reg:%d irq:%d\n", reg_idx, irq_idx);
+ return;
+ }
+
spin_lock_irqsave(&intr->irq_lock, irq_flags);
- sde_hw_intr_clear_intr_status_nolock(intr, irq_idx);
+ SDE_REG_WRITE(&intr->hw, intr->sde_irq_tbl[reg_idx].clr_off,
+ sde_irq_map[irq_idx].irq_mask);
spin_unlock_irqrestore(&intr->irq_lock, irq_flags);
}
@@ -1272,9 +1245,6 @@ static u32 sde_hw_intr_get_interrupt_status(struct sde_hw_intr *intr,
SDE_REG_WRITE(&intr->hw, intr->sde_irq_tbl[reg_idx].clr_off,
intr_status);
- /* ensure register writes go through */
- wmb();
-
spin_unlock_irqrestore(&intr->irq_lock, irq_flags);
return intr_status;
@@ -1321,7 +1291,6 @@ static void __setup_intr_ops(struct sde_hw_intr_ops *ops)
ops->disable_all_irqs = sde_hw_intr_disable_irqs;
ops->get_valid_interrupts = sde_hw_intr_get_valid_interrupts;
ops->get_interrupt_sources = sde_hw_intr_get_interrupt_sources;
- ops->get_interrupt_statuses = sde_hw_intr_get_interrupt_statuses;
ops->clear_interrupt_status = sde_hw_intr_clear_interrupt_status;
ops->clear_intr_status_nolock = sde_hw_intr_clear_intr_status_nolock;
ops->clear_intr_status_force_mask =
@@ -1469,7 +1438,6 @@ void sde_hw_intr_destroy(struct sde_hw_intr *intr)
if (intr) {
kfree(intr->sde_irq_tbl);
kfree(intr->cache_irq_mask);
- kfree(intr->save_irq_status);
kfree(intr);
}
}
@@ -1578,13 +1546,6 @@ struct sde_hw_intr *sde_hw_intr_init(void __iomem *addr,
goto exit;
}
- intr->save_irq_status = kcalloc(intr->sde_irq_size, sizeof(u32),
- GFP_KERNEL);
- if (intr->save_irq_status == NULL) {
- ret = -ENOMEM;
- goto exit;
- }
-
spin_lock_init(&intr->irq_lock);
return intr;
@@ -1592,7 +1553,6 @@ struct sde_hw_intr *sde_hw_intr_init(void __iomem *addr,
exit:
kfree(intr->sde_irq_tbl);
kfree(intr->cache_irq_mask);
- kfree(intr->save_irq_status);
kfree(intr);
return ERR_PTR(ret);
}