summaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-sirfsoc.c
diff options
context:
space:
mode:
authorBarry Song <Baohua.Song@csr.com>2014-12-10 18:53:51 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-10 20:41:15 -0500
commite9bc7363d634e8d2ef1955106c53f8266d724353 (patch)
tree9a68c5601a6ea0d4622882f1d40197a6991fb119 /drivers/rtc/rtc-sirfsoc.c
parent09e427f87d345967503bb3c64854e11412c584f5 (diff)
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>
Diffstat (limited to 'drivers/rtc/rtc-sirfsoc.c')
-rw-r--r--drivers/rtc/rtc-sirfsoc.c27
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 {
47 unsigned irq_wake; 47 unsigned irq_wake;
48 /* Overflow for every 8 years extra time */ 48 /* Overflow for every 8 years extra time */
49 u32 overflow_rtc; 49 u32 overflow_rtc;
50 spinlock_t lock;
50#ifdef CONFIG_PM 51#ifdef CONFIG_PM
51 u32 saved_counter; 52 u32 saved_counter;
52 u32 saved_overflow_rtc; 53 u32 saved_overflow_rtc;
@@ -61,7 +62,7 @@ static int sirfsoc_rtc_read_alarm(struct device *dev,
61 62
62 rtcdrv = dev_get_drvdata(dev); 63 rtcdrv = dev_get_drvdata(dev);
63 64
64 local_irq_disable(); 65 spin_lock_irq(&rtcdrv->lock);
65 66
66 rtc_count = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN); 67 rtc_count = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN);
67 68
@@ -84,7 +85,8 @@ static int sirfsoc_rtc_read_alarm(struct device *dev,
84 if (sirfsoc_rtc_iobrg_readl( 85 if (sirfsoc_rtc_iobrg_readl(
85 rtcdrv->rtc_base + RTC_STATUS) & SIRFSOC_RTC_AL0E) 86 rtcdrv->rtc_base + RTC_STATUS) & SIRFSOC_RTC_AL0E)
86 alrm->enabled = 1; 87 alrm->enabled = 1;
87 local_irq_enable(); 88
89 spin_unlock_irq(&rtcdrv->lock);
88 90
89 return 0; 91 return 0;
90} 92}
@@ -99,7 +101,7 @@ static int sirfsoc_rtc_set_alarm(struct device *dev,
99 if (alrm->enabled) { 101 if (alrm->enabled) {
100 rtc_tm_to_time(&(alrm->time), &rtc_alarm); 102 rtc_tm_to_time(&(alrm->time), &rtc_alarm);
101 103
102 local_irq_disable(); 104 spin_lock_irq(&rtcdrv->lock);
103 105
104 rtc_status_reg = sirfsoc_rtc_iobrg_readl( 106 rtc_status_reg = sirfsoc_rtc_iobrg_readl(
105 rtcdrv->rtc_base + RTC_STATUS); 107 rtcdrv->rtc_base + RTC_STATUS);
@@ -123,14 +125,15 @@ static int sirfsoc_rtc_set_alarm(struct device *dev,
123 rtc_status_reg |= SIRFSOC_RTC_AL0E; 125 rtc_status_reg |= SIRFSOC_RTC_AL0E;
124 sirfsoc_rtc_iobrg_writel( 126 sirfsoc_rtc_iobrg_writel(
125 rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS); 127 rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS);
126 local_irq_enable(); 128
129 spin_unlock_irq(&rtcdrv->lock);
127 } else { 130 } else {
128 /* 131 /*
129 * if this function was called with enabled=0 132 * if this function was called with enabled=0
130 * then it could mean that the application is 133 * then it could mean that the application is
131 * trying to cancel an ongoing alarm 134 * trying to cancel an ongoing alarm
132 */ 135 */
133 local_irq_disable(); 136 spin_lock_irq(&rtcdrv->lock);
134 137
135 rtc_status_reg = sirfsoc_rtc_iobrg_readl( 138 rtc_status_reg = sirfsoc_rtc_iobrg_readl(
136 rtcdrv->rtc_base + RTC_STATUS); 139 rtcdrv->rtc_base + RTC_STATUS);
@@ -146,7 +149,7 @@ static int sirfsoc_rtc_set_alarm(struct device *dev,
146 rtcdrv->rtc_base + RTC_STATUS); 149 rtcdrv->rtc_base + RTC_STATUS);
147 } 150 }
148 151
149 local_irq_enable(); 152 spin_unlock_irq(&rtcdrv->lock);
150 } 153 }
151 154
152 return 0; 155 return 0;
@@ -217,7 +220,7 @@ static int sirfsoc_rtc_alarm_irq_enable(struct device *dev,
217 220
218 rtcdrv = dev_get_drvdata(dev); 221 rtcdrv = dev_get_drvdata(dev);
219 222
220 local_irq_disable(); 223 spin_lock_irq(&rtcdrv->lock);
221 224
222 rtc_status_reg = sirfsoc_rtc_iobrg_readl( 225 rtc_status_reg = sirfsoc_rtc_iobrg_readl(
223 rtcdrv->rtc_base + RTC_STATUS); 226 rtcdrv->rtc_base + RTC_STATUS);
@@ -227,7 +230,8 @@ static int sirfsoc_rtc_alarm_irq_enable(struct device *dev,
227 rtc_status_reg &= ~SIRFSOC_RTC_AL0E; 230 rtc_status_reg &= ~SIRFSOC_RTC_AL0E;
228 231
229 sirfsoc_rtc_iobrg_writel(rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS); 232 sirfsoc_rtc_iobrg_writel(rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS);
230 local_irq_enable(); 233
234 spin_unlock_irq(&rtcdrv->lock);
231 235
232 return 0; 236 return 0;
233 237
@@ -248,6 +252,8 @@ static irqreturn_t sirfsoc_rtc_irq_handler(int irq, void *pdata)
248 unsigned long rtc_status_reg = 0x0; 252 unsigned long rtc_status_reg = 0x0;
249 unsigned long events = 0x0; 253 unsigned long events = 0x0;
250 254
255 spin_lock(&rtcdrv->lock);
256
251 rtc_status_reg = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_STATUS); 257 rtc_status_reg = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_STATUS);
252 /* this bit will be set ONLY if an alarm was active 258 /* this bit will be set ONLY if an alarm was active
253 * and it expired NOW 259 * and it expired NOW
@@ -265,6 +271,9 @@ static irqreturn_t sirfsoc_rtc_irq_handler(int irq, void *pdata)
265 rtc_status_reg &= ~(SIRFSOC_RTC_AL0E); 271 rtc_status_reg &= ~(SIRFSOC_RTC_AL0E);
266 } 272 }
267 sirfsoc_rtc_iobrg_writel(rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS); 273 sirfsoc_rtc_iobrg_writel(rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS);
274
275 spin_unlock(&rtcdrv->lock);
276
268 /* this should wake up any apps polling/waiting on the read 277 /* this should wake up any apps polling/waiting on the read
269 * after setting the alarm 278 * after setting the alarm
270 */ 279 */
@@ -292,6 +301,8 @@ static int sirfsoc_rtc_probe(struct platform_device *pdev)
292 if (rtcdrv == NULL) 301 if (rtcdrv == NULL)
293 return -ENOMEM; 302 return -ENOMEM;
294 303
304 spin_lock_init(&rtcdrv->lock);
305
295 err = of_property_read_u32(np, "reg", &rtcdrv->rtc_base); 306 err = of_property_read_u32(np, "reg", &rtcdrv->rtc_base);
296 if (err) { 307 if (err) {
297 dev_err(&pdev->dev, "unable to find base address of rtc node in dtb\n"); 308 dev_err(&pdev->dev, "unable to find base address of rtc node in dtb\n");