aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-dev.c')
-rw-r--r--drivers/rtc/rtc-dev.c70
1 files changed, 47 insertions, 23 deletions
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 90dfa0df747a..0a870b7e5c32 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -13,6 +13,7 @@
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/rtc.h> 15#include <linux/rtc.h>
16#include <linux/smp_lock.h>
16#include "rtc-core.h" 17#include "rtc-core.h"
17 18
18static dev_t rtc_devt; 19static dev_t rtc_devt;
@@ -26,8 +27,11 @@ static int rtc_dev_open(struct inode *inode, struct file *file)
26 struct rtc_device, char_dev); 27 struct rtc_device, char_dev);
27 const struct rtc_class_ops *ops = rtc->ops; 28 const struct rtc_class_ops *ops = rtc->ops;
28 29
29 if (test_and_set_bit_lock(RTC_DEV_BUSY, &rtc->flags)) 30 lock_kernel();
30 return -EBUSY; 31 if (test_and_set_bit_lock(RTC_DEV_BUSY, &rtc->flags)) {
32 err = -EBUSY;
33 goto out;
34 }
31 35
32 file->private_data = rtc; 36 file->private_data = rtc;
33 37
@@ -37,11 +41,13 @@ static int rtc_dev_open(struct inode *inode, struct file *file)
37 rtc->irq_data = 0; 41 rtc->irq_data = 0;
38 spin_unlock_irq(&rtc->irq_lock); 42 spin_unlock_irq(&rtc->irq_lock);
39 43
40 return 0; 44 goto out;
41 } 45 }
42 46
43 /* something has gone wrong */ 47 /* something has gone wrong */
44 clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags); 48 clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags);
49out:
50 unlock_kernel();
45 return err; 51 return err;
46} 52}
47 53
@@ -203,7 +209,7 @@ static unsigned int rtc_dev_poll(struct file *file, poll_table *wait)
203 return (data != 0) ? (POLLIN | POLLRDNORM) : 0; 209 return (data != 0) ? (POLLIN | POLLRDNORM) : 0;
204} 210}
205 211
206static int rtc_dev_ioctl(struct inode *inode, struct file *file, 212static long rtc_dev_ioctl(struct file *file,
207 unsigned int cmd, unsigned long arg) 213 unsigned int cmd, unsigned long arg)
208{ 214{
209 int err = 0; 215 int err = 0;
@@ -213,6 +219,10 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
213 struct rtc_wkalrm alarm; 219 struct rtc_wkalrm alarm;
214 void __user *uarg = (void __user *) arg; 220 void __user *uarg = (void __user *) arg;
215 221
222 err = mutex_lock_interruptible(&rtc->ops_lock);
223 if (err)
224 return -EBUSY;
225
216 /* check that the calling task has appropriate permissions 226 /* check that the calling task has appropriate permissions
217 * for certain ioctls. doing this check here is useful 227 * for certain ioctls. doing this check here is useful
218 * to avoid duplicate code in each driver. 228 * to avoid duplicate code in each driver.
@@ -221,26 +231,31 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
221 case RTC_EPOCH_SET: 231 case RTC_EPOCH_SET:
222 case RTC_SET_TIME: 232 case RTC_SET_TIME:
223 if (!capable(CAP_SYS_TIME)) 233 if (!capable(CAP_SYS_TIME))
224 return -EACCES; 234 err = -EACCES;
225 break; 235 break;
226 236
227 case RTC_IRQP_SET: 237 case RTC_IRQP_SET:
228 if (arg > rtc->max_user_freq && !capable(CAP_SYS_RESOURCE)) 238 if (arg > rtc->max_user_freq && !capable(CAP_SYS_RESOURCE))
229 return -EACCES; 239 err = -EACCES;
230 break; 240 break;
231 241
232 case RTC_PIE_ON: 242 case RTC_PIE_ON:
233 if (rtc->irq_freq > rtc->max_user_freq && 243 if (rtc->irq_freq > rtc->max_user_freq &&
234 !capable(CAP_SYS_RESOURCE)) 244 !capable(CAP_SYS_RESOURCE))
235 return -EACCES; 245 err = -EACCES;
236 break; 246 break;
237 } 247 }
238 248
249 if (err)
250 goto done;
251
239 /* try the driver's ioctl interface */ 252 /* try the driver's ioctl interface */
240 if (ops->ioctl) { 253 if (ops->ioctl) {
241 err = ops->ioctl(rtc->dev.parent, cmd, arg); 254 err = ops->ioctl(rtc->dev.parent, cmd, arg);
242 if (err != -ENOIOCTLCMD) 255 if (err != -ENOIOCTLCMD) {
256 mutex_unlock(&rtc->ops_lock);
243 return err; 257 return err;
258 }
244 } 259 }
245 260
246 /* if the driver does not provide the ioctl interface 261 /* if the driver does not provide the ioctl interface
@@ -259,15 +274,19 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
259 274
260 switch (cmd) { 275 switch (cmd) {
261 case RTC_ALM_READ: 276 case RTC_ALM_READ:
277 mutex_unlock(&rtc->ops_lock);
278
262 err = rtc_read_alarm(rtc, &alarm); 279 err = rtc_read_alarm(rtc, &alarm);
263 if (err < 0) 280 if (err < 0)
264 return err; 281 return err;
265 282
266 if (copy_to_user(uarg, &alarm.time, sizeof(tm))) 283 if (copy_to_user(uarg, &alarm.time, sizeof(tm)))
267 return -EFAULT; 284 err = -EFAULT;
268 break; 285 return err;
269 286
270 case RTC_ALM_SET: 287 case RTC_ALM_SET:
288 mutex_unlock(&rtc->ops_lock);
289
271 if (copy_from_user(&alarm.time, uarg, sizeof(tm))) 290 if (copy_from_user(&alarm.time, uarg, sizeof(tm)))
272 return -EFAULT; 291 return -EFAULT;
273 292
@@ -315,24 +334,26 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
315 } 334 }
316 } 335 }
317 336
318 err = rtc_set_alarm(rtc, &alarm); 337 return rtc_set_alarm(rtc, &alarm);
319 break;
320 338
321 case RTC_RD_TIME: 339 case RTC_RD_TIME:
340 mutex_unlock(&rtc->ops_lock);
341
322 err = rtc_read_time(rtc, &tm); 342 err = rtc_read_time(rtc, &tm);
323 if (err < 0) 343 if (err < 0)
324 return err; 344 return err;
325 345
326 if (copy_to_user(uarg, &tm, sizeof(tm))) 346 if (copy_to_user(uarg, &tm, sizeof(tm)))
327 return -EFAULT; 347 err = -EFAULT;
328 break; 348 return err;
329 349
330 case RTC_SET_TIME: 350 case RTC_SET_TIME:
351 mutex_unlock(&rtc->ops_lock);
352
331 if (copy_from_user(&tm, uarg, sizeof(tm))) 353 if (copy_from_user(&tm, uarg, sizeof(tm)))
332 return -EFAULT; 354 return -EFAULT;
333 355
334 err = rtc_set_time(rtc, &tm); 356 return rtc_set_time(rtc, &tm);
335 break;
336 357
337 case RTC_PIE_ON: 358 case RTC_PIE_ON:
338 err = rtc_irq_set_state(rtc, NULL, 1); 359 err = rtc_irq_set_state(rtc, NULL, 1);
@@ -370,34 +391,37 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
370 break; 391 break;
371#endif 392#endif
372 case RTC_WKALM_SET: 393 case RTC_WKALM_SET:
394 mutex_unlock(&rtc->ops_lock);
373 if (copy_from_user(&alarm, uarg, sizeof(alarm))) 395 if (copy_from_user(&alarm, uarg, sizeof(alarm)))
374 return -EFAULT; 396 return -EFAULT;
375 397
376 err = rtc_set_alarm(rtc, &alarm); 398 return rtc_set_alarm(rtc, &alarm);
377 break;
378 399
379 case RTC_WKALM_RD: 400 case RTC_WKALM_RD:
401 mutex_unlock(&rtc->ops_lock);
380 err = rtc_read_alarm(rtc, &alarm); 402 err = rtc_read_alarm(rtc, &alarm);
381 if (err < 0) 403 if (err < 0)
382 return err; 404 return err;
383 405
384 if (copy_to_user(uarg, &alarm, sizeof(alarm))) 406 if (copy_to_user(uarg, &alarm, sizeof(alarm)))
385 return -EFAULT; 407 err = -EFAULT;
386 break; 408 return err;
387 409
388#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL 410#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
389 case RTC_UIE_OFF: 411 case RTC_UIE_OFF:
390 clear_uie(rtc); 412 clear_uie(rtc);
391 return 0; 413 break;
392 414
393 case RTC_UIE_ON: 415 case RTC_UIE_ON:
394 return set_uie(rtc); 416 err = set_uie(rtc);
395#endif 417#endif
396 default: 418 default:
397 err = -ENOTTY; 419 err = -ENOTTY;
398 break; 420 break;
399 } 421 }
400 422
423done:
424 mutex_unlock(&rtc->ops_lock);
401 return err; 425 return err;
402} 426}
403 427
@@ -426,7 +450,7 @@ static const struct file_operations rtc_dev_fops = {
426 .llseek = no_llseek, 450 .llseek = no_llseek,
427 .read = rtc_dev_read, 451 .read = rtc_dev_read,
428 .poll = rtc_dev_poll, 452 .poll = rtc_dev_poll,
429 .ioctl = rtc_dev_ioctl, 453 .unlocked_ioctl = rtc_dev_ioctl,
430 .open = rtc_dev_open, 454 .open = rtc_dev_open,
431 .release = rtc_dev_release, 455 .release = rtc_dev_release,
432 .fasync = rtc_dev_fasync, 456 .fasync = rtc_dev_fasync,