bool hal_rtc_is_lp_irq(void) { u16 irqsta; irqsta = rtc_read(RTC_IRQ_STA); /* read clear */ if (unlikely(!(irqsta & RTC_IRQ_STA_AL))) { #ifndef USER_BUILD_KERNEL if (irqsta & RTC_IRQ_STA_LP) rtc_lp_exception(); #endif return true; } return false; }
static void rtc_tasklet_handler(unsigned long data) { u16 irqsta, pdn1, pdn2, spar1; bool pwron_alm = false; spin_lock(&rtc_lock); irqsta = rtc_read(RTC_IRQ_STA); /* read clear */ if (unlikely(!(irqsta & RTC_IRQ_STA_AL))) { #ifndef USER_BUILD_KERNEL if (irqsta & RTC_IRQ_STA_LP) rtc_lp_exception(); #endif spin_unlock(&rtc_lock); enable_irq(MT6573_RTC_IRQ_LINE); return; } #if RTC_RELPWR_WHEN_XRST { /* set AUTO bit because AUTO = 0 when PWREN = 1 and alarm occurs */ u16 bbpu = rtc_read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_AUTO; rtc_write(RTC_BBPU, bbpu); rtc_write_trigger(); } #endif pdn1 = rtc_read(RTC_PDN1); pdn2 = rtc_read(RTC_PDN2); spar1 = rtc_read(RTC_SPAR1); if (pdn1 & 0x0080) { /* power-on time is available */ u16 now_sec, now_min, now_hou, now_dom, now_mth; u16 irqen, min, hou, dom, mth; now_sec = rtc_read(RTC_TC_SEC); now_min = rtc_read(RTC_TC_MIN); now_hou = rtc_read(RTC_TC_HOU); now_dom = rtc_read(RTC_TC_DOM); now_mth = rtc_read(RTC_TC_MTH); if (rtc_read(RTC_TC_SEC) < now_sec) { /* SEC has carried */ now_sec = rtc_read(RTC_TC_SEC); now_min = rtc_read(RTC_TC_MIN); now_hou = rtc_read(RTC_TC_HOU); now_dom = rtc_read(RTC_TC_DOM); now_mth = rtc_read(RTC_TC_MTH); } min = spar1 & 0x003f; hou = (spar1 & 0x07c0) >> 6; dom = (spar1 & 0xf800) >> 11; mth = pdn2 & 0x000f; if (now_mth == mth && now_dom == dom && now_hou == hou && now_min == min && now_sec >= (RTC_PWRON_SEC - 1) && now_sec <= (RTC_PWRON_SEC + 4)) { rtc_write(RTC_PDN1, pdn1 & ~0x0080); rtc_write(RTC_PDN2, pdn2 | 0x0010); rtc_write_trigger(); pwron_alm = true; } else { /* set power-on alarm when power-on time is available */ rtc_write(RTC_AL_MTH, mth); rtc_write(RTC_AL_DOM, dom); rtc_write(RTC_AL_HOU, hou); rtc_write(RTC_AL_MIN, min); rtc_write(RTC_AL_SEC, RTC_PWRON_SEC); rtc_write(RTC_AL_MASK, 0x0050); /* mask YEA and DOW */ rtc_write_trigger(); irqen = rtc_read(RTC_IRQ_EN) | RTC_IRQ_EN_ONESHOT_AL; rtc_write(RTC_IRQ_EN, irqen); rtc_write_trigger(); } }