Loading drivers/platform/msm/ipa/ipa_v2/ipa_interrupts.c +30 −9 Original line number Diff line number Diff line Loading @@ -151,29 +151,50 @@ fail_alloc_work: return res; } static inline bool is_uc_irq(int irq_num) { if (ipa_interrupt_to_cb[irq_num].interrupt >= IPA_UC_IRQ_0 && ipa_interrupt_to_cb[irq_num].interrupt <= IPA_UC_IRQ_3) return true; else return false; } static void ipa_process_interrupts(bool isr_context) { u32 reg; u32 bmsk; u32 i = 0; u32 en; bool uc_irq; en = ipa_read_reg(ipa_ctx->mmio, IPA_IRQ_EN_EE_n_ADDR(ipa_ee)); reg = ipa_read_reg(ipa_ctx->mmio, IPA_IRQ_STTS_EE_n_ADDR(ipa_ee)); while (en & reg) { /* Clear interrupt before processing to avoid bmsk = 1; for (i = 0; i < IPA_IRQ_NUM_MAX; i++) { if (!(en & reg & bmsk)) { bmsk = bmsk << 1; continue; } uc_irq = is_uc_irq(i); /* Clear uC interrupt before processing to avoid clearing unhandled interrupts */ if (uc_irq) ipa_write_reg(ipa_ctx->mmio, IPA_IRQ_CLR_EE_n_ADDR(ipa_ee), reg); IPA_IRQ_CLR_EE_n_ADDR(ipa_ee), bmsk); /* Process the interrupts */ bmsk = 1; for (i = 0; i < IPA_IRQ_NUM_MAX; i++) { if (en & reg & bmsk) handle_interrupt(i, isr_context); /* Clear non uC interrupt after processing to avoid clearing interrupt data */ if (!uc_irq) ipa_write_reg(ipa_ctx->mmio, IPA_IRQ_CLR_EE_n_ADDR(ipa_ee), bmsk); bmsk = bmsk << 1; } /* Check pending interrupts that may have been raised since last read */ reg = ipa_read_reg(ipa_ctx->mmio, Loading drivers/platform/msm/ipa/ipa_v3/ipa_interrupts.c +24 −1 Original line number Diff line number Diff line Loading @@ -235,6 +235,15 @@ static void ipa3_tx_suspend_interrupt_wa(void) IPADBG_LOW("Exit\n"); } static inline bool is_uc_irq(int irq_num) { if (ipa_interrupt_to_cb[irq_num].interrupt >= IPA_UC_IRQ_0 && ipa_interrupt_to_cb[irq_num].interrupt <= IPA_UC_IRQ_3) return true; else return false; } static void ipa3_process_interrupts(bool isr_context) { u32 reg; Loading @@ -242,6 +251,7 @@ static void ipa3_process_interrupts(bool isr_context) u32 i = 0; u32 en; unsigned long flags; bool uc_irq; IPADBG_LOW("Enter\n"); Loading @@ -252,6 +262,14 @@ static void ipa3_process_interrupts(bool isr_context) bmsk = 1; for (i = 0; i < IPA_IRQ_NUM_MAX; i++) { if (en & reg & bmsk) { uc_irq = is_uc_irq(i); /* Clear uC interrupt before processing to avoid clearing unhandled interrupts */ if (uc_irq) ipa3_uc_rg10_write_reg(IPA_IRQ_CLR_EE_n, ipa_ee, bmsk); /* * handle the interrupt with spin_lock * unlocked to avoid calling client in atomic Loading @@ -262,6 +280,12 @@ static void ipa3_process_interrupts(bool isr_context) spin_unlock_irqrestore(&suspend_wa_lock, flags); ipa3_handle_interrupt(i, isr_context); spin_lock_irqsave(&suspend_wa_lock, flags); /* Clear non uC interrupt after processing to avoid clearing interrupt data */ if (!uc_irq) ipa3_uc_rg10_write_reg(IPA_IRQ_CLR_EE_n, ipa_ee, bmsk); } bmsk = bmsk << 1; } Loading @@ -272,7 +296,6 @@ static void ipa3_process_interrupts(bool isr_context) if (ipa3_ctx->apply_rg10_wa && ipa3_ctx->uc_ctx.uc_failed) break; ipa3_uc_rg10_write_reg(IPA_IRQ_CLR_EE_n, ipa_ee, reg); reg = ipahal_read_reg_n(IPA_IRQ_STTS_EE_n, ipa_ee); /* since the suspend interrupt HW bug we must * read again the EN register, otherwise the while is endless Loading Loading
drivers/platform/msm/ipa/ipa_v2/ipa_interrupts.c +30 −9 Original line number Diff line number Diff line Loading @@ -151,29 +151,50 @@ fail_alloc_work: return res; } static inline bool is_uc_irq(int irq_num) { if (ipa_interrupt_to_cb[irq_num].interrupt >= IPA_UC_IRQ_0 && ipa_interrupt_to_cb[irq_num].interrupt <= IPA_UC_IRQ_3) return true; else return false; } static void ipa_process_interrupts(bool isr_context) { u32 reg; u32 bmsk; u32 i = 0; u32 en; bool uc_irq; en = ipa_read_reg(ipa_ctx->mmio, IPA_IRQ_EN_EE_n_ADDR(ipa_ee)); reg = ipa_read_reg(ipa_ctx->mmio, IPA_IRQ_STTS_EE_n_ADDR(ipa_ee)); while (en & reg) { /* Clear interrupt before processing to avoid bmsk = 1; for (i = 0; i < IPA_IRQ_NUM_MAX; i++) { if (!(en & reg & bmsk)) { bmsk = bmsk << 1; continue; } uc_irq = is_uc_irq(i); /* Clear uC interrupt before processing to avoid clearing unhandled interrupts */ if (uc_irq) ipa_write_reg(ipa_ctx->mmio, IPA_IRQ_CLR_EE_n_ADDR(ipa_ee), reg); IPA_IRQ_CLR_EE_n_ADDR(ipa_ee), bmsk); /* Process the interrupts */ bmsk = 1; for (i = 0; i < IPA_IRQ_NUM_MAX; i++) { if (en & reg & bmsk) handle_interrupt(i, isr_context); /* Clear non uC interrupt after processing to avoid clearing interrupt data */ if (!uc_irq) ipa_write_reg(ipa_ctx->mmio, IPA_IRQ_CLR_EE_n_ADDR(ipa_ee), bmsk); bmsk = bmsk << 1; } /* Check pending interrupts that may have been raised since last read */ reg = ipa_read_reg(ipa_ctx->mmio, Loading
drivers/platform/msm/ipa/ipa_v3/ipa_interrupts.c +24 −1 Original line number Diff line number Diff line Loading @@ -235,6 +235,15 @@ static void ipa3_tx_suspend_interrupt_wa(void) IPADBG_LOW("Exit\n"); } static inline bool is_uc_irq(int irq_num) { if (ipa_interrupt_to_cb[irq_num].interrupt >= IPA_UC_IRQ_0 && ipa_interrupt_to_cb[irq_num].interrupt <= IPA_UC_IRQ_3) return true; else return false; } static void ipa3_process_interrupts(bool isr_context) { u32 reg; Loading @@ -242,6 +251,7 @@ static void ipa3_process_interrupts(bool isr_context) u32 i = 0; u32 en; unsigned long flags; bool uc_irq; IPADBG_LOW("Enter\n"); Loading @@ -252,6 +262,14 @@ static void ipa3_process_interrupts(bool isr_context) bmsk = 1; for (i = 0; i < IPA_IRQ_NUM_MAX; i++) { if (en & reg & bmsk) { uc_irq = is_uc_irq(i); /* Clear uC interrupt before processing to avoid clearing unhandled interrupts */ if (uc_irq) ipa3_uc_rg10_write_reg(IPA_IRQ_CLR_EE_n, ipa_ee, bmsk); /* * handle the interrupt with spin_lock * unlocked to avoid calling client in atomic Loading @@ -262,6 +280,12 @@ static void ipa3_process_interrupts(bool isr_context) spin_unlock_irqrestore(&suspend_wa_lock, flags); ipa3_handle_interrupt(i, isr_context); spin_lock_irqsave(&suspend_wa_lock, flags); /* Clear non uC interrupt after processing to avoid clearing interrupt data */ if (!uc_irq) ipa3_uc_rg10_write_reg(IPA_IRQ_CLR_EE_n, ipa_ee, bmsk); } bmsk = bmsk << 1; } Loading @@ -272,7 +296,6 @@ static void ipa3_process_interrupts(bool isr_context) if (ipa3_ctx->apply_rg10_wa && ipa3_ctx->uc_ctx.uc_failed) break; ipa3_uc_rg10_write_reg(IPA_IRQ_CLR_EE_n, ipa_ee, reg); reg = ipahal_read_reg_n(IPA_IRQ_STTS_EE_n, ipa_ee); /* since the suspend interrupt HW bug we must * read again the EN register, otherwise the while is endless Loading