Commit e9bc7363 authored by Barry Song's avatar Barry Song Committed by Linus Torvalds

drivers/rtc/rtc-sirfsoc.c: replace local_irq_disable by spin_lock_irq for SMP safety

Signed-off-by: default avatarBarry Song <Baohua.Song@csr.com>
Cc: hao liu <hao.liu@csr.com>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 09e427f8
...@@ -47,6 +47,7 @@ struct sirfsoc_rtc_drv { ...@@ -47,6 +47,7 @@ struct sirfsoc_rtc_drv {
unsigned irq_wake; unsigned irq_wake;
/* Overflow for every 8 years extra time */ /* Overflow for every 8 years extra time */
u32 overflow_rtc; u32 overflow_rtc;
spinlock_t lock;
#ifdef CONFIG_PM #ifdef CONFIG_PM
u32 saved_counter; u32 saved_counter;
u32 saved_overflow_rtc; u32 saved_overflow_rtc;
...@@ -61,7 +62,7 @@ static int sirfsoc_rtc_read_alarm(struct device *dev, ...@@ -61,7 +62,7 @@ static int sirfsoc_rtc_read_alarm(struct device *dev,
rtcdrv = dev_get_drvdata(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); rtc_count = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN);
...@@ -84,7 +85,8 @@ static int sirfsoc_rtc_read_alarm(struct device *dev, ...@@ -84,7 +85,8 @@ static int sirfsoc_rtc_read_alarm(struct device *dev,
if (sirfsoc_rtc_iobrg_readl( if (sirfsoc_rtc_iobrg_readl(
rtcdrv->rtc_base + RTC_STATUS) & SIRFSOC_RTC_AL0E) rtcdrv->rtc_base + RTC_STATUS) & SIRFSOC_RTC_AL0E)
alrm->enabled = 1; alrm->enabled = 1;
local_irq_enable();
spin_unlock_irq(&rtcdrv->lock);
return 0; return 0;
} }
...@@ -99,7 +101,7 @@ static int sirfsoc_rtc_set_alarm(struct device *dev, ...@@ -99,7 +101,7 @@ static int sirfsoc_rtc_set_alarm(struct device *dev,
if (alrm->enabled) { if (alrm->enabled) {
rtc_tm_to_time(&(alrm->time), &rtc_alarm); rtc_tm_to_time(&(alrm->time), &rtc_alarm);
local_irq_disable(); spin_lock_irq(&rtcdrv->lock);
rtc_status_reg = sirfsoc_rtc_iobrg_readl( rtc_status_reg = sirfsoc_rtc_iobrg_readl(
rtcdrv->rtc_base + RTC_STATUS); rtcdrv->rtc_base + RTC_STATUS);
...@@ -123,14 +125,15 @@ static int sirfsoc_rtc_set_alarm(struct device *dev, ...@@ -123,14 +125,15 @@ static int sirfsoc_rtc_set_alarm(struct device *dev,
rtc_status_reg |= SIRFSOC_RTC_AL0E; rtc_status_reg |= SIRFSOC_RTC_AL0E;
sirfsoc_rtc_iobrg_writel( sirfsoc_rtc_iobrg_writel(
rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS); rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS);
local_irq_enable();
spin_unlock_irq(&rtcdrv->lock);
} else { } else {
/* /*
* if this function was called with enabled=0 * if this function was called with enabled=0
* then it could mean that the application is * then it could mean that the application is
* trying to cancel an ongoing alarm * trying to cancel an ongoing alarm
*/ */
local_irq_disable(); spin_lock_irq(&rtcdrv->lock);
rtc_status_reg = sirfsoc_rtc_iobrg_readl( rtc_status_reg = sirfsoc_rtc_iobrg_readl(
rtcdrv->rtc_base + RTC_STATUS); rtcdrv->rtc_base + RTC_STATUS);
...@@ -146,7 +149,7 @@ static int sirfsoc_rtc_set_alarm(struct device *dev, ...@@ -146,7 +149,7 @@ static int sirfsoc_rtc_set_alarm(struct device *dev,
rtcdrv->rtc_base + RTC_STATUS); rtcdrv->rtc_base + RTC_STATUS);
} }
local_irq_enable(); spin_unlock_irq(&rtcdrv->lock);
} }
return 0; return 0;
...@@ -217,7 +220,7 @@ static int sirfsoc_rtc_alarm_irq_enable(struct device *dev, ...@@ -217,7 +220,7 @@ static int sirfsoc_rtc_alarm_irq_enable(struct device *dev,
rtcdrv = dev_get_drvdata(dev); rtcdrv = dev_get_drvdata(dev);
local_irq_disable(); spin_lock_irq(&rtcdrv->lock);
rtc_status_reg = sirfsoc_rtc_iobrg_readl( rtc_status_reg = sirfsoc_rtc_iobrg_readl(
rtcdrv->rtc_base + RTC_STATUS); rtcdrv->rtc_base + RTC_STATUS);
...@@ -227,7 +230,8 @@ static int sirfsoc_rtc_alarm_irq_enable(struct device *dev, ...@@ -227,7 +230,8 @@ static int sirfsoc_rtc_alarm_irq_enable(struct device *dev,
rtc_status_reg &= ~SIRFSOC_RTC_AL0E; rtc_status_reg &= ~SIRFSOC_RTC_AL0E;
sirfsoc_rtc_iobrg_writel(rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS); sirfsoc_rtc_iobrg_writel(rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS);
local_irq_enable();
spin_unlock_irq(&rtcdrv->lock);
return 0; return 0;
...@@ -248,6 +252,8 @@ static irqreturn_t sirfsoc_rtc_irq_handler(int irq, void *pdata) ...@@ -248,6 +252,8 @@ static irqreturn_t sirfsoc_rtc_irq_handler(int irq, void *pdata)
unsigned long rtc_status_reg = 0x0; unsigned long rtc_status_reg = 0x0;
unsigned long events = 0x0; unsigned long events = 0x0;
spin_lock(&rtcdrv->lock);
rtc_status_reg = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_STATUS); rtc_status_reg = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_STATUS);
/* this bit will be set ONLY if an alarm was active /* this bit will be set ONLY if an alarm was active
* and it expired NOW * and it expired NOW
...@@ -265,6 +271,9 @@ static irqreturn_t sirfsoc_rtc_irq_handler(int irq, void *pdata) ...@@ -265,6 +271,9 @@ static irqreturn_t sirfsoc_rtc_irq_handler(int irq, void *pdata)
rtc_status_reg &= ~(SIRFSOC_RTC_AL0E); rtc_status_reg &= ~(SIRFSOC_RTC_AL0E);
} }
sirfsoc_rtc_iobrg_writel(rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS); 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 /* this should wake up any apps polling/waiting on the read
* after setting the alarm * after setting the alarm
*/ */
...@@ -292,6 +301,8 @@ static int sirfsoc_rtc_probe(struct platform_device *pdev) ...@@ -292,6 +301,8 @@ static int sirfsoc_rtc_probe(struct platform_device *pdev)
if (rtcdrv == NULL) if (rtcdrv == NULL)
return -ENOMEM; return -ENOMEM;
spin_lock_init(&rtcdrv->lock);
err = of_property_read_u32(np, "reg", &rtcdrv->rtc_base); err = of_property_read_u32(np, "reg", &rtcdrv->rtc_base);
if (err) { if (err) {
dev_err(&pdev->dev, "unable to find base address of rtc node in dtb\n"); dev_err(&pdev->dev, "unable to find base address of rtc node in dtb\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment