diff options
| -rw-r--r-- | drivers/rtc/rtc-sirfsoc.c | 27 | 
1 files changed, 19 insertions, 8 deletions
| diff --git a/drivers/rtc/rtc-sirfsoc.c b/drivers/rtc/rtc-sirfsoc.c index a9ea7d181380..d2ac6688e5c7 100644 --- a/drivers/rtc/rtc-sirfsoc.c +++ b/drivers/rtc/rtc-sirfsoc.c @@ -47,6 +47,7 @@ struct sirfsoc_rtc_drv {  	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; @@ -61,7 +62,7 @@ static int sirfsoc_rtc_read_alarm(struct device *dev,  	rtcdrv = dev_get_drvdata(dev); -	local_irq_disable(); +	spin_lock_irq(&rtcdrv->lock);  	rtc_count = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN); @@ -84,7 +85,8 @@ static int sirfsoc_rtc_read_alarm(struct device *dev,  	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;  } @@ -99,7 +101,7 @@ static int sirfsoc_rtc_set_alarm(struct device *dev,  	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); @@ -123,14 +125,15 @@ static int sirfsoc_rtc_set_alarm(struct device *dev,  		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); @@ -146,7 +149,7 @@ static int sirfsoc_rtc_set_alarm(struct device *dev,  					rtcdrv->rtc_base + RTC_STATUS);  		} -		local_irq_enable(); +		spin_unlock_irq(&rtcdrv->lock);  	}  	return 0; @@ -217,7 +220,7 @@ static int sirfsoc_rtc_alarm_irq_enable(struct device *dev,  	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); @@ -227,7 +230,8 @@ static int sirfsoc_rtc_alarm_irq_enable(struct device *dev,  		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; @@ -248,6 +252,8 @@ static irqreturn_t sirfsoc_rtc_irq_handler(int irq, void *pdata)  	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 @@ -265,6 +271,9 @@ static irqreturn_t sirfsoc_rtc_irq_handler(int irq, void *pdata)  		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  	 */ @@ -292,6 +301,8 @@ static int sirfsoc_rtc_probe(struct platform_device *pdev)  	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"); | 
