aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/efirtc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/efirtc.c')
-rw-r--r--drivers/char/efirtc.c37
1 files changed, 21 insertions, 16 deletions
diff --git a/drivers/char/efirtc.c b/drivers/char/efirtc.c
index 49233f589874..67fbd7aab5db 100644
--- a/drivers/char/efirtc.c
+++ b/drivers/char/efirtc.c
@@ -28,6 +28,7 @@
28 */ 28 */
29 29
30 30
31#include <linux/smp_lock.h>
31#include <linux/types.h> 32#include <linux/types.h>
32#include <linux/errno.h> 33#include <linux/errno.h>
33#include <linux/miscdevice.h> 34#include <linux/miscdevice.h>
@@ -36,8 +37,9 @@
36#include <linux/rtc.h> 37#include <linux/rtc.h>
37#include <linux/proc_fs.h> 38#include <linux/proc_fs.h>
38#include <linux/efi.h> 39#include <linux/efi.h>
40#include <linux/smp_lock.h>
41#include <linux/uaccess.h>
39 42
40#include <asm/uaccess.h>
41#include <asm/system.h> 43#include <asm/system.h>
42 44
43#define EFI_RTC_VERSION "0.4" 45#define EFI_RTC_VERSION "0.4"
@@ -50,8 +52,8 @@
50 52
51static DEFINE_SPINLOCK(efi_rtc_lock); 53static DEFINE_SPINLOCK(efi_rtc_lock);
52 54
53static int efi_rtc_ioctl(struct inode *inode, struct file *file, 55static long efi_rtc_ioctl(struct file *file, unsigned int cmd,
54 unsigned int cmd, unsigned long arg); 56 unsigned long arg);
55 57
56#define is_leap(year) \ 58#define is_leap(year) \
57 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) 59 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
@@ -145,9 +147,8 @@ convert_from_efi_time(efi_time_t *eft, struct rtc_time *wtime)
145 } 147 }
146} 148}
147 149
148static int 150static long efi_rtc_ioctl(struct file *file, unsigned int cmd,
149efi_rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 151 unsigned long arg)
150 unsigned long arg)
151{ 152{
152 153
153 efi_status_t status; 154 efi_status_t status;
@@ -174,13 +175,13 @@ efi_rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
174 return -EINVAL; 175 return -EINVAL;
175 176
176 case RTC_RD_TIME: 177 case RTC_RD_TIME:
177 178 lock_kernel();
178 spin_lock_irqsave(&efi_rtc_lock, flags); 179 spin_lock_irqsave(&efi_rtc_lock, flags);
179 180
180 status = efi.get_time(&eft, &cap); 181 status = efi.get_time(&eft, &cap);
181 182
182 spin_unlock_irqrestore(&efi_rtc_lock,flags); 183 spin_unlock_irqrestore(&efi_rtc_lock,flags);
183 184 unlock_kernel();
184 if (status != EFI_SUCCESS) { 185 if (status != EFI_SUCCESS) {
185 /* should never happen */ 186 /* should never happen */
186 printk(KERN_ERR "efitime: can't read time\n"); 187 printk(KERN_ERR "efitime: can't read time\n");
@@ -202,11 +203,13 @@ efi_rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
202 203
203 convert_to_efi_time(&wtime, &eft); 204 convert_to_efi_time(&wtime, &eft);
204 205
206 lock_kernel();
205 spin_lock_irqsave(&efi_rtc_lock, flags); 207 spin_lock_irqsave(&efi_rtc_lock, flags);
206 208
207 status = efi.set_time(&eft); 209 status = efi.set_time(&eft);
208 210
209 spin_unlock_irqrestore(&efi_rtc_lock,flags); 211 spin_unlock_irqrestore(&efi_rtc_lock,flags);
212 unlock_kernel();
210 213
211 return status == EFI_SUCCESS ? 0 : -EINVAL; 214 return status == EFI_SUCCESS ? 0 : -EINVAL;
212 215
@@ -222,6 +225,7 @@ efi_rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
222 225
223 convert_to_efi_time(&wtime, &eft); 226 convert_to_efi_time(&wtime, &eft);
224 227
228 lock_kernel();
225 spin_lock_irqsave(&efi_rtc_lock, flags); 229 spin_lock_irqsave(&efi_rtc_lock, flags);
226 /* 230 /*
227 * XXX Fixme: 231 * XXX Fixme:
@@ -232,16 +236,19 @@ efi_rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
232 status = efi.set_wakeup_time((efi_bool_t)enabled, &eft); 236 status = efi.set_wakeup_time((efi_bool_t)enabled, &eft);
233 237
234 spin_unlock_irqrestore(&efi_rtc_lock,flags); 238 spin_unlock_irqrestore(&efi_rtc_lock,flags);
239 unlock_kernel();
235 240
236 return status == EFI_SUCCESS ? 0 : -EINVAL; 241 return status == EFI_SUCCESS ? 0 : -EINVAL;
237 242
238 case RTC_WKALM_RD: 243 case RTC_WKALM_RD:
239 244
245 lock_kernel();
240 spin_lock_irqsave(&efi_rtc_lock, flags); 246 spin_lock_irqsave(&efi_rtc_lock, flags);
241 247
242 status = efi.get_wakeup_time((efi_bool_t *)&enabled, (efi_bool_t *)&pending, &eft); 248 status = efi.get_wakeup_time((efi_bool_t *)&enabled, (efi_bool_t *)&pending, &eft);
243 249
244 spin_unlock_irqrestore(&efi_rtc_lock,flags); 250 spin_unlock_irqrestore(&efi_rtc_lock,flags);
251 unlock_kernel();
245 252
246 if (status != EFI_SUCCESS) return -EINVAL; 253 if (status != EFI_SUCCESS) return -EINVAL;
247 254
@@ -255,7 +262,7 @@ efi_rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
255 return copy_to_user(&ewp->time, &wtime, 262 return copy_to_user(&ewp->time, &wtime,
256 sizeof(struct rtc_time)) ? -EFAULT : 0; 263 sizeof(struct rtc_time)) ? -EFAULT : 0;
257 } 264 }
258 return -EINVAL; 265 return -ENOTTY;
259} 266}
260 267
261/* 268/*
@@ -264,19 +271,18 @@ efi_rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
264 * up things on a close. 271 * up things on a close.
265 */ 272 */
266 273
267static int 274static int efi_rtc_open(struct inode *inode, struct file *file)
268efi_rtc_open(struct inode *inode, struct file *file)
269{ 275{
270 /* 276 /*
271 * nothing special to do here 277 * nothing special to do here
272 * We do accept multiple open files at the same time as we 278 * We do accept multiple open files at the same time as we
273 * synchronize on the per call operation. 279 * synchronize on the per call operation.
274 */ 280 */
281 cycle_kernel_lock();
275 return 0; 282 return 0;
276} 283}
277 284
278static int 285static int efi_rtc_close(struct inode *inode, struct file *file)
279efi_rtc_close(struct inode *inode, struct file *file)
280{ 286{
281 return 0; 287 return 0;
282} 288}
@@ -287,13 +293,12 @@ efi_rtc_close(struct inode *inode, struct file *file)
287 293
288static const struct file_operations efi_rtc_fops = { 294static const struct file_operations efi_rtc_fops = {
289 .owner = THIS_MODULE, 295 .owner = THIS_MODULE,
290 .ioctl = efi_rtc_ioctl, 296 .unlocked_ioctl = efi_rtc_ioctl,
291 .open = efi_rtc_open, 297 .open = efi_rtc_open,
292 .release = efi_rtc_close, 298 .release = efi_rtc_close,
293}; 299};
294 300
295static struct miscdevice efi_rtc_dev= 301static struct miscdevice efi_rtc_dev= {
296{
297 EFI_RTC_MINOR, 302 EFI_RTC_MINOR,
298 "efirtc", 303 "efirtc",
299 &efi_rtc_fops 304 &efi_rtc_fops