diff options
author | Barry Song <Baohua.Song@csr.com> | 2014-12-10 18:53:51 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-10 20:41:15 -0500 |
commit | e9bc7363d634e8d2ef1955106c53f8266d724353 (patch) | |
tree | 9a68c5601a6ea0d4622882f1d40197a6991fb119 /drivers/rtc/rtc-sirfsoc.c | |
parent | 09e427f87d345967503bb3c64854e11412c584f5 (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.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 { | |||
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"); |