static void msm_irq_disable(unsigned int irq) { void __iomem *reg = VIC_INT_TO_REG_ADDR(VIC_INT_ENCLEAR0, irq); unsigned index = VIC_INT_TO_REG_INDEX(irq); uint32_t mask = 1UL << (irq & 31); int smsm_irq = msm_irq_to_smsm[irq]; if (!(msm_irq_shadow_reg[index].int_en[1] & mask)) { msm_irq_shadow_reg[index].int_en[0] &= ~mask; writel(mask, reg); mb(); if (smsm_irq == 0) msm_irq_idle_disable[index] &= ~mask; else { mask = 1UL << (smsm_irq - 1); msm_irq_smsm_wake_enable[0] &= ~mask; } } }
/* * Restore interrupt subsystem from sleep -- phase 2. * Poke the specified pending interrupts into interrupt hardware. */ void msm_irq_exit_sleep2(uint32_t irq_mask, uint32_t wakeup_reason, uint32_t pending) { int i; if (msm_irq_debug_mask & IRQ_DEBUG_SLEEP) DPRINT_REGS(VIC_IRQ_STATUS, "%s %x %x %x now", __func__, irq_mask, pending, wakeup_reason); for (i = 0; pending && i < ARRAY_SIZE(msm_irq_to_smsm); i++) { unsigned reg_offset = VIC_INT_TO_REG_ADDR(0, i); uint32_t reg_mask = 1UL << (i & 31); int smsm_irq = msm_irq_to_smsm[i]; uint32_t smsm_mask; if (smsm_irq == 0) continue; smsm_mask = 1U << (smsm_irq - 1); if (!(pending & smsm_mask)) continue; pending &= ~smsm_mask; if (msm_irq_debug_mask & IRQ_DEBUG_SLEEP_INT) DPRINT_REGS(VIC_IRQ_STATUS, "%s: irq %d still pending %x now", __func__, i, pending); #if 0 /* debug intetrrupt trigger */ if (readl(VIC_IRQ_STATUS0 + reg_offset) & reg_mask) writel(reg_mask, VIC_INT_CLEAR0 + reg_offset); #endif if (readl(VIC_IRQ_STATUS0 + reg_offset) & reg_mask) continue; writel(reg_mask, VIC_SOFTINT0 + reg_offset); if (msm_irq_debug_mask & IRQ_DEBUG_SLEEP_INT_TRIGGER) DPRINT_REGS(VIC_IRQ_STATUS, "%s: irq %d need trigger, now", __func__, i); } }
void msm_trigger_irq(int irq) { void __iomem *reg = VIC_INT_TO_REG_ADDR(VIC_SOFTINT0, irq); uint32_t mask = 1UL << (irq & 31); writel(mask, reg); }
static void msm_irq_ack(unsigned int irq) { void __iomem *reg = VIC_INT_TO_REG_ADDR(VIC_INT_CLEAR0, irq); irq = 1 << (irq & 31); writel(irq, reg); }