#define RTC_CALIB_DEF 0x198233
#define RTC_CALIB_MASK 0x1FFFFF
+#define RTC_ALRM_MASK BIT(1)
+#define RTC_MSEC 1000
struct xlnx_rtc_dev {
struct rtc_device *rtc;
static int xlnx_rtc_alarm_irq_enable(struct device *dev, u32 enabled)
{
struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
+ unsigned int status;
+ ulong timeout;
+
+ timeout = jiffies + msecs_to_jiffies(RTC_MSEC);
+
+ if (enabled) {
+ while (1) {
+ status = readl(xrtcdev->reg_base + RTC_INT_STS);
+ if (!((status & RTC_ALRM_MASK) == RTC_ALRM_MASK))
+ break;
+
+ if (time_after_eq(jiffies, timeout)) {
+ dev_err(dev, "Time out occur, while clearing alarm status bit\n");
+ return -ETIMEDOUT;
+ }
+ writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_STS);
+ }
- if (enabled)
writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_EN);
- else
+ } else {
writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_DIS);
+ }
return 0;
}
if (!(status & (RTC_INT_SEC | RTC_INT_ALRM)))
return IRQ_NONE;
- /* Clear RTC_INT_ALRM interrupt only */
- writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_STS);
+ /* Disable RTC_INT_ALRM interrupt only */
+ writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_DIS);
if (status & RTC_INT_ALRM)
rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_AF);