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;
}
Beispiel #2
0
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();
		}
	}