drivers/rtc/rtc-sirfsoc.c: replace local_irq_disable by spin_lock_irq for SMP safety
Signed-off-by: Barry Song <Baohua.Song@csr.com> Cc: hao liu <hao.liu@csr.com> Cc: Alessandro Zummo <a.zummo@towertech.it> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
09e427f87d
commit
e9bc7363d6
1 changed files with 19 additions and 8 deletions
|
@ -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");
|
||||
|
|
Loading…
Reference in a new issue