unsigned                irq_wake;
        /* Overflow for every 8 years extra time */
        u32                     overflow_rtc;
+       spinlock_t              lock;
 #ifdef CONFIG_PM
        u32             saved_counter;
        u32             saved_overflow_rtc;
 
        rtcdrv = dev_get_drvdata(dev);
 
-       local_irq_disable();
+       spin_lock_irq(&rtcdrv->lock);
 
        rtc_count = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN);
 
        if (sirfsoc_rtc_iobrg_readl(
                        rtcdrv->rtc_base + RTC_STATUS) & SIRFSOC_RTC_AL0E)
                alrm->enabled = 1;
-       local_irq_enable();
+
+       spin_unlock_irq(&rtcdrv->lock);
 
        return 0;
 }
        if (alrm->enabled) {
                rtc_tm_to_time(&(alrm->time), &rtc_alarm);
 
-               local_irq_disable();
+               spin_lock_irq(&rtcdrv->lock);
 
                rtc_status_reg = sirfsoc_rtc_iobrg_readl(
                                rtcdrv->rtc_base + RTC_STATUS);
                rtc_status_reg |= SIRFSOC_RTC_AL0E;
                sirfsoc_rtc_iobrg_writel(
                        rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS);
-               local_irq_enable();
+
+               spin_unlock_irq(&rtcdrv->lock);
        } else {
                /*
                 * if this function was called with enabled=0
                 * then it could mean that the application is
                 * trying to cancel an ongoing alarm
                 */
-               local_irq_disable();
+               spin_lock_irq(&rtcdrv->lock);
 
                rtc_status_reg = sirfsoc_rtc_iobrg_readl(
                                rtcdrv->rtc_base + RTC_STATUS);
                                        rtcdrv->rtc_base + RTC_STATUS);
                }
 
-               local_irq_enable();
+               spin_unlock_irq(&rtcdrv->lock);
        }
 
        return 0;
 
        rtcdrv = dev_get_drvdata(dev);
 
-       local_irq_disable();
+       spin_lock_irq(&rtcdrv->lock);
 
        rtc_status_reg = sirfsoc_rtc_iobrg_readl(
                                rtcdrv->rtc_base + RTC_STATUS);
                rtc_status_reg &= ~SIRFSOC_RTC_AL0E;
 
        sirfsoc_rtc_iobrg_writel(rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS);
-       local_irq_enable();
+
+       spin_unlock_irq(&rtcdrv->lock);
 
        return 0;
 
        unsigned long rtc_status_reg = 0x0;
        unsigned long events = 0x0;
 
+       spin_lock(&rtcdrv->lock);
+
        rtc_status_reg = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_STATUS);
        /* this bit will be set ONLY if an alarm was active
         * and it expired NOW
                rtc_status_reg &= ~(SIRFSOC_RTC_AL0E);
        }
        sirfsoc_rtc_iobrg_writel(rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS);
+
+       spin_unlock(&rtcdrv->lock);
+
        /* this should wake up any apps polling/waiting on the read
         * after setting the alarm
         */
        if (rtcdrv == NULL)
                return -ENOMEM;
 
+       spin_lock_init(&rtcdrv->lock);
+
        err = of_property_read_u32(np, "reg", &rtcdrv->rtc_base);
        if (err) {
                dev_err(&pdev->dev, "unable to find base address of rtc node in dtb\n");