Loading drivers/gpu/drm/msm/sde/sde_core_irq.c +38 −0 Original line number Diff line number Diff line Loading @@ -202,6 +202,44 @@ int sde_core_irq_disable(struct sde_kms *sde_kms, int *irq_idxs, u32 irq_count) return ret; } /** * sde_core_irq_disable_nolock - disable core interrupt given by the index * without lock * @sde_kms: Pointer to sde kms context * @irq_idx: interrupt index */ int sde_core_irq_disable_nolock(struct sde_kms *sde_kms, int irq_idx) { int ret = 0; if (!sde_kms || !sde_kms->hw_intr || !sde_kms->irq_obj.enable_counts) { SDE_ERROR("invalid params\n"); return -EINVAL; } if (irq_idx < 0 || irq_idx >= sde_kms->hw_intr->irq_idx_tbl_size) { SDE_ERROR("invalid IRQ index: [%d]\n", irq_idx); return -EINVAL; } SDE_DEBUG("irq_idx=%d enable_count=%d\n", irq_idx, atomic_read(&sde_kms->irq_obj.enable_counts[irq_idx])); SDE_EVT32(irq_idx, atomic_read(&sde_kms->irq_obj.enable_counts[irq_idx])); if (atomic_dec_return(&sde_kms->irq_obj.enable_counts[irq_idx]) == 0) { ret = sde_kms->hw_intr->ops.disable_irq_nolock( sde_kms->hw_intr, irq_idx); if (ret) SDE_ERROR("Fail to disable IRQ for irq_idx:%d\n", irq_idx); SDE_DEBUG("irq_idx=%d ret=%d\n", irq_idx, ret); } return ret; } u32 sde_core_irq_read_nolock(struct sde_kms *sde_kms, int irq_idx, bool clear) { if (!sde_kms || !sde_kms->hw_intr || Loading drivers/gpu/drm/msm/sde/sde_core_irq.h +13 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,19 @@ int sde_core_irq_disable( int *irq_idxs, uint32_t irq_count); /** * sde_core_irq_disable_nolock - no lock version of sde_core_irq_disable * @sde_kms: SDE handle * @irq_idx: Irq index * @return: 0 for success disabling IRQ, otherwise failure * * This function increments count on each enable and decrements on each * disable. Interrupts is disabled if count is 0 after decrement. */ int sde_core_irq_disable_nolock( struct sde_kms *sde_kms, int irq_idx); /** * sde_core_irq_read - IRQ helper function for reading IRQ status * @sde_kms: SDE handle Loading drivers/gpu/drm/msm/sde/sde_hw_interrupts.c +21 −4 Original line number Diff line number Diff line Loading @@ -910,10 +910,9 @@ static int sde_hw_intr_enable_irq(struct sde_hw_intr *intr, int irq_idx) return 0; } static int sde_hw_intr_disable_irq(struct sde_hw_intr *intr, int irq_idx) static int sde_hw_intr_disable_irq_nolock(struct sde_hw_intr *intr, int irq_idx) { int reg_idx; unsigned long irq_flags; const struct sde_intr_reg *reg; const struct sde_irq_type *irq; const char *dbgstr = NULL; Loading @@ -931,7 +930,6 @@ static int sde_hw_intr_disable_irq(struct sde_hw_intr *intr, int irq_idx) reg_idx = irq->reg_idx; reg = &sde_intr_set[reg_idx]; spin_lock_irqsave(&intr->irq_lock, irq_flags); cache_irq_mask = intr->cache_irq_mask[reg_idx]; if ((cache_irq_mask & irq->irq_mask) == 0) { dbgstr = "SDE IRQ is already cleared:"; Loading @@ -949,7 +947,6 @@ static int sde_hw_intr_disable_irq(struct sde_hw_intr *intr, int irq_idx) intr->cache_irq_mask[reg_idx] = cache_irq_mask; } spin_unlock_irqrestore(&intr->irq_lock, irq_flags); pr_debug("%s MASK:0x%.8x, CACHE-MASK:0x%.8x\n", dbgstr, irq->irq_mask, cache_irq_mask); Loading @@ -957,6 +954,25 @@ static int sde_hw_intr_disable_irq(struct sde_hw_intr *intr, int irq_idx) return 0; } static int sde_hw_intr_disable_irq(struct sde_hw_intr *intr, int irq_idx) { unsigned long irq_flags; if (!intr) return -EINVAL; if (irq_idx < 0 || irq_idx >= ARRAY_SIZE(sde_irq_map)) { pr_err("invalid IRQ index: [%d]\n", irq_idx); return -EINVAL; } spin_lock_irqsave(&intr->irq_lock, irq_flags); sde_hw_intr_disable_irq_nolock(intr, irq_idx); spin_unlock_irqrestore(&intr->irq_lock, irq_flags); return 0; } static int sde_hw_intr_clear_irqs(struct sde_hw_intr *intr) { int i; Loading Loading @@ -1141,6 +1157,7 @@ static void __setup_intr_ops(struct sde_hw_intr_ops *ops) ops->irq_idx_lookup = sde_hw_intr_irqidx_lookup; ops->enable_irq = sde_hw_intr_enable_irq; ops->disable_irq = sde_hw_intr_disable_irq; ops->disable_irq_nolock = sde_hw_intr_disable_irq_nolock; ops->dispatch_irqs = sde_hw_intr_dispatch_irq; ops->clear_all_irqs = sde_hw_intr_clear_irqs; ops->disable_all_irqs = sde_hw_intr_disable_irqs; Loading drivers/gpu/drm/msm/sde/sde_hw_interrupts.h +10 −0 Original line number Diff line number Diff line Loading @@ -138,6 +138,16 @@ struct sde_hw_intr_ops { struct sde_hw_intr *intr, int irq_idx); /** * disable_irq_nolock - Disable IRQ based on IRQ index without lock * @intr: HW interrupt handle * @irq_idx: Lookup irq index return from irq_idx_lookup * @return: 0 for success, otherwise failure */ int (*disable_irq_nolock)( struct sde_hw_intr *intr, int irq_idx); /** * clear_all_irqs - Clears all the interrupts (i.e. acknowledges * any asserted IRQs). Useful during reset. Loading Loading
drivers/gpu/drm/msm/sde/sde_core_irq.c +38 −0 Original line number Diff line number Diff line Loading @@ -202,6 +202,44 @@ int sde_core_irq_disable(struct sde_kms *sde_kms, int *irq_idxs, u32 irq_count) return ret; } /** * sde_core_irq_disable_nolock - disable core interrupt given by the index * without lock * @sde_kms: Pointer to sde kms context * @irq_idx: interrupt index */ int sde_core_irq_disable_nolock(struct sde_kms *sde_kms, int irq_idx) { int ret = 0; if (!sde_kms || !sde_kms->hw_intr || !sde_kms->irq_obj.enable_counts) { SDE_ERROR("invalid params\n"); return -EINVAL; } if (irq_idx < 0 || irq_idx >= sde_kms->hw_intr->irq_idx_tbl_size) { SDE_ERROR("invalid IRQ index: [%d]\n", irq_idx); return -EINVAL; } SDE_DEBUG("irq_idx=%d enable_count=%d\n", irq_idx, atomic_read(&sde_kms->irq_obj.enable_counts[irq_idx])); SDE_EVT32(irq_idx, atomic_read(&sde_kms->irq_obj.enable_counts[irq_idx])); if (atomic_dec_return(&sde_kms->irq_obj.enable_counts[irq_idx]) == 0) { ret = sde_kms->hw_intr->ops.disable_irq_nolock( sde_kms->hw_intr, irq_idx); if (ret) SDE_ERROR("Fail to disable IRQ for irq_idx:%d\n", irq_idx); SDE_DEBUG("irq_idx=%d ret=%d\n", irq_idx, ret); } return ret; } u32 sde_core_irq_read_nolock(struct sde_kms *sde_kms, int irq_idx, bool clear) { if (!sde_kms || !sde_kms->hw_intr || Loading
drivers/gpu/drm/msm/sde/sde_core_irq.h +13 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,19 @@ int sde_core_irq_disable( int *irq_idxs, uint32_t irq_count); /** * sde_core_irq_disable_nolock - no lock version of sde_core_irq_disable * @sde_kms: SDE handle * @irq_idx: Irq index * @return: 0 for success disabling IRQ, otherwise failure * * This function increments count on each enable and decrements on each * disable. Interrupts is disabled if count is 0 after decrement. */ int sde_core_irq_disable_nolock( struct sde_kms *sde_kms, int irq_idx); /** * sde_core_irq_read - IRQ helper function for reading IRQ status * @sde_kms: SDE handle Loading
drivers/gpu/drm/msm/sde/sde_hw_interrupts.c +21 −4 Original line number Diff line number Diff line Loading @@ -910,10 +910,9 @@ static int sde_hw_intr_enable_irq(struct sde_hw_intr *intr, int irq_idx) return 0; } static int sde_hw_intr_disable_irq(struct sde_hw_intr *intr, int irq_idx) static int sde_hw_intr_disable_irq_nolock(struct sde_hw_intr *intr, int irq_idx) { int reg_idx; unsigned long irq_flags; const struct sde_intr_reg *reg; const struct sde_irq_type *irq; const char *dbgstr = NULL; Loading @@ -931,7 +930,6 @@ static int sde_hw_intr_disable_irq(struct sde_hw_intr *intr, int irq_idx) reg_idx = irq->reg_idx; reg = &sde_intr_set[reg_idx]; spin_lock_irqsave(&intr->irq_lock, irq_flags); cache_irq_mask = intr->cache_irq_mask[reg_idx]; if ((cache_irq_mask & irq->irq_mask) == 0) { dbgstr = "SDE IRQ is already cleared:"; Loading @@ -949,7 +947,6 @@ static int sde_hw_intr_disable_irq(struct sde_hw_intr *intr, int irq_idx) intr->cache_irq_mask[reg_idx] = cache_irq_mask; } spin_unlock_irqrestore(&intr->irq_lock, irq_flags); pr_debug("%s MASK:0x%.8x, CACHE-MASK:0x%.8x\n", dbgstr, irq->irq_mask, cache_irq_mask); Loading @@ -957,6 +954,25 @@ static int sde_hw_intr_disable_irq(struct sde_hw_intr *intr, int irq_idx) return 0; } static int sde_hw_intr_disable_irq(struct sde_hw_intr *intr, int irq_idx) { unsigned long irq_flags; if (!intr) return -EINVAL; if (irq_idx < 0 || irq_idx >= ARRAY_SIZE(sde_irq_map)) { pr_err("invalid IRQ index: [%d]\n", irq_idx); return -EINVAL; } spin_lock_irqsave(&intr->irq_lock, irq_flags); sde_hw_intr_disable_irq_nolock(intr, irq_idx); spin_unlock_irqrestore(&intr->irq_lock, irq_flags); return 0; } static int sde_hw_intr_clear_irqs(struct sde_hw_intr *intr) { int i; Loading Loading @@ -1141,6 +1157,7 @@ static void __setup_intr_ops(struct sde_hw_intr_ops *ops) ops->irq_idx_lookup = sde_hw_intr_irqidx_lookup; ops->enable_irq = sde_hw_intr_enable_irq; ops->disable_irq = sde_hw_intr_disable_irq; ops->disable_irq_nolock = sde_hw_intr_disable_irq_nolock; ops->dispatch_irqs = sde_hw_intr_dispatch_irq; ops->clear_all_irqs = sde_hw_intr_clear_irqs; ops->disable_all_irqs = sde_hw_intr_disable_irqs; Loading
drivers/gpu/drm/msm/sde/sde_hw_interrupts.h +10 −0 Original line number Diff line number Diff line Loading @@ -138,6 +138,16 @@ struct sde_hw_intr_ops { struct sde_hw_intr *intr, int irq_idx); /** * disable_irq_nolock - Disable IRQ based on IRQ index without lock * @intr: HW interrupt handle * @irq_idx: Lookup irq index return from irq_idx_lookup * @return: 0 for success, otherwise failure */ int (*disable_irq_nolock)( struct sde_hw_intr *intr, int irq_idx); /** * clear_all_irqs - Clears all the interrupts (i.e. acknowledges * any asserted IRQs). Useful during reset. Loading