static __tcmfunc irqreturn_t _TVC_InterruptHandler(int irq, void *dev_id) { TVC_REG_IRQ_STS status = TVC_REG->IRQ_STATUS; mt6575_irq_mask(MT6575_TVC_IRQ_ID); //printk("_TVC_InterruptHandler, status: %x\n", status); if (1 == status.IRQ2) { status.IRQ2 = 0; printk("[WARN][TVC] Overrun !!\n"); } if (1 == status.IRQ0) { status.IRQ0 = 0; //printk("wake up tvc_checkline!!\n"); wake_up_interruptible(&_tvcContext.tvc_checkline); TVOUT_On_TVC_Done(); } OUTREG32(&TVC_REG->IRQ_STATUS, AS_UINT32(&status)); mt6575_irq_unmask(MT6575_TVC_IRQ_ID); return IRQ_HANDLED; }
static void sc_go_to_sleep(u32 timeout, kal_bool en_deep_idle) { struct mtk_irq_mask mask; unsigned int i, wakesrc, irq, clk_mux, clksettle; __asm__ __volatile__("cpsid i @ arch_local_irq_disable" : : : "memory", "cc"); // set i bit to disable interrupt mt6575_irq_mask_all(&mask); // mask all interrupts gpt_irq_ack(); if (en_deep_idle) { mt6575_irq_unmask(MT6575_SLEEP_IRQ_ID); } else { mt6575_irq_unmask(MT6575_GPT_IRQ_ID); } gpt_one_shot_irq(timeout); if (en_deep_idle) { /* keep SRCLKENA high (26M on) when in sleep mode */ DRV_WriteReg32(SC_CLK_CON, DRV_Reg32(SC_CLK_CON) | SC_CLK_CON_SRCLKEN); /* set SYSCLK settle time to 1T 32K */ clksettle = DRV_Reg32(SC_CLK_SETTLE); DRV_WriteReg32(SC_CLK_SETTLE, SC_CLK_SETTLE_26MON); DRV_WriteReg32(SC_PAUSE, 0xffffffff); /* unmask wakeup sources */ DRV_WriteReg32(SC_WAKEUP_EVENT_MASK, ~sc_wake_src); /* unmask Pause Interrupt and Pause Abort */ DRV_WriteReg32(SC_ISR_MASK, 0x0001); DRV_WriteReg32(SC_TIMER_CON, SC_TIMER_CON_EN); DRV_WriteReg32(SC_TIMER_CMD, SC_TIMER_CMD_KEY | SC_TIMER_CMD_CONWR | SC_TIMER_CMD_CNTWR | SC_TIMER_CMD_WR); while (!(DRV_Reg32(SC_TIMER_STA) & SC_TIMER_STA_CMDCPL)); DRV_WriteReg32(SC_TIMER_CMD, SC_TIMER_CMD_KEY | SC_TIMER_CMD_PAUSE); while (!(DRV_Reg32(SC_TIMER_STA) & SC_TIMER_STA_CMDCPL)); } __asm__ __volatile__("dsb" : : : "memory"); __asm__ __volatile__("wfi"); // enter wfi if (en_deep_idle) { /* delay to make sure ISR_STATUS can be cleared later */ udelay(100); /* for cleaning wakeup source status */ DRV_WriteReg32(SC_DBG_WAKEUP, 0); DRV_WriteReg32(SC_TIMER_CON, SC_TIMER_CON_DBG | SC_TIMER_CON_EN); DRV_WriteReg32(SC_TIMER_CMD, SC_TIMER_CMD_KEY | SC_TIMER_CMD_CONWR | SC_TIMER_CMD_WR); while (!(DRV_Reg32(SC_TIMER_STA) & SC_TIMER_STA_CMDCPL)); DRV_WriteReg32(SC_ISR_MASK, 0x0007); DRV_WriteReg32(SC_ISR_STATUS, 0x0007); /* write 1 clear */ /* restore SC_CLK_SETTLE and SC_CLK_CON */ DRV_WriteReg32(SC_CLK_SETTLE, clksettle); DRV_WriteReg32(SC_CLK_CON, DRV_Reg32(SC_CLK_CON) & ~SC_CLK_CON_SRCLKEN); } gpt_irq_ack(); mt6575_irq_ack(MT6575_GPT_IRQ_ID); if (en_deep_idle) { mt6575_irq_ack(MT6575_SLEEP_IRQ_ID); } mt6575_irq_mask_restore(&mask); // restore all interrupts __asm__ __volatile__("cpsie i @ arch_local_irq_enable" : : : "memory", "cc"); // clear i bit to enable interrupt }