void __init avic_init_irq(void __iomem *base, int nr_irqs) { int i; g_icoll_base = base; mxs_reset_block(base + HW_ICOLL_CTRL, 0); for (i = 0; i < nr_irqs; i++) { __raw_writel(0, g_icoll_base + HW_ICOLL_INTERRUPTn(i)); set_irq_chip(i, &icoll_chip); set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } __raw_writel(BF_ICOLL_LEVELACK_IRQLEVELACK (BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0), g_icoll_base + HW_ICOLL_LEVELACK); __raw_writel(BF_ICOLL_LEVELACK_IRQLEVELACK (BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL1), g_icoll_base + HW_ICOLL_LEVELACK); __raw_writel(BF_ICOLL_LEVELACK_IRQLEVELACK (BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL2), g_icoll_base + HW_ICOLL_LEVELACK); __raw_writel(BF_ICOLL_LEVELACK_IRQLEVELACK (BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL3), g_icoll_base + HW_ICOLL_LEVELACK); __raw_writel(0, g_icoll_base + HW_ICOLL_VECTOR); /* Barrier */ (void)__raw_readl(g_icoll_base + HW_ICOLL_STAT); }
/* * This routine is called just before the processor goes to sleep. * It's job is to disable all interrupts except those that have * been defined as wake up sources by icoll_set_wake_irq. * * Return -1 if no IRQ has been configured as a wake up source. */ int mxs_icoll_suspend(void) { int result = -1; unsigned int irq; for (irq = 0; irq < ARRAY_SIZE(saved_irq_setting); irq++) { saved_irq_setting[irq] = __raw_readl(g_icoll_base + HW_ICOLL_INTERRUPTn(irq)); if (is_wakeup_source[irq]) { __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE, g_icoll_base + HW_ICOLL_INTERRUPTn(irq)); result = 0; } else { __raw_writel(0, g_icoll_base + HW_ICOLL_INTERRUPTn(irq)); } } return result; }
/* * This routine is called shortly after we wake up to restore the * saved interrupt configuration. */ void mxs_icoll_resume(void) { unsigned int irq; for (irq = 0; irq < ARRAY_SIZE(saved_irq_setting); irq++) { __raw_writel(saved_irq_setting[irq], g_icoll_base + HW_ICOLL_INTERRUPTn(irq)); } }
/////////////////////////////////////////////////////////////////////////////// //! See hw_icoll.h for details. /////////////////////////////////////////////////////////////////////////////// bool hw_icoll_EnableVector(ICOLL_IRQ_enums_t eIrqVectorNumber, bool bEnable) { bool b_previousEnableState; b_previousEnableState= (HW_ICOLL_INTERRUPTn(eIrqVectorNumber).B.ENABLE)?true:false; if (bEnable) HW_ICOLL_INTERRUPTn_SET(eIrqVectorNumber, BM_ICOLL_INTERRUPTn_ENABLE); else HW_ICOLL_INTERRUPTn_CLR(eIrqVectorNumber, BM_ICOLL_INTERRUPTn_ENABLE); return b_previousEnableState; }
void __init avic_init_irq(void __iomem *base, int nr_irqs) { int i; g_icoll_base = base; /* Reset icoll */ __raw_writel(BM_ICOLL_CTRL_SFTRST, g_icoll_base + HW_ICOLL_CTRL_CLR); for (i = 0; i < 100000; i++) { if (!(__raw_readl(g_icoll_base + HW_ICOLL_CTRL) & BM_ICOLL_CTRL_SFTRST)) break; udelay(2); } if (i >= 100000) { printk(KERN_ERR "%s:%d timeout when enableing\n", __func__, __LINE__); return; } __raw_writel(BM_ICOLL_CTRL_CLKGATE, g_icoll_base + HW_ICOLL_CTRL_CLR); for (i = 0; i < nr_irqs; i++) { __raw_writel(0, g_icoll_base + HW_ICOLL_INTERRUPTn(i)); set_irq_chip(i, &icoll_chip); set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } __raw_writel(BF_ICOLL_LEVELACK_IRQLEVELACK (BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0), g_icoll_base + HW_ICOLL_LEVELACK); __raw_writel(BF_ICOLL_LEVELACK_IRQLEVELACK (BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL1), g_icoll_base + HW_ICOLL_LEVELACK); __raw_writel(BF_ICOLL_LEVELACK_IRQLEVELACK (BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL2), g_icoll_base + HW_ICOLL_LEVELACK); __raw_writel(BF_ICOLL_LEVELACK_IRQLEVELACK (BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL3), g_icoll_base + HW_ICOLL_LEVELACK); __raw_writel(0, g_icoll_base + HW_ICOLL_VECTOR); /* Barrier */ (void)__raw_readl(g_icoll_base + HW_ICOLL_STAT); }
static void icoll_unmask_irq(struct irq_data *d) { __raw_writel(BM_ICOLL_INTR_ENABLE, icoll_priv.intr + SET_REG + HW_ICOLL_INTERRUPTn(d->hwirq)); }