diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/efirtc.c | 35 |
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 | ||
52 | static DEFINE_SPINLOCK(efi_rtc_lock); | 53 | static DEFINE_SPINLOCK(efi_rtc_lock); |
53 | 54 | ||
54 | static int efi_rtc_ioctl(struct inode *inode, struct file *file, | 55 | static 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 | ||
149 | static int | 150 | static long efi_rtc_ioctl(struct file *file, unsigned int cmd, |
150 | efi_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 | ||
268 | static int | 274 | static int efi_rtc_open(struct inode *inode, struct file *file) |
269 | efi_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 | ||
280 | static int | 285 | static int efi_rtc_close(struct inode *inode, struct file *file) |
281 | efi_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 | ||
290 | static const struct file_operations efi_rtc_fops = { | 294 | static 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 | ||
297 | static struct miscdevice efi_rtc_dev= | 301 | static 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 |