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