diff options
Diffstat (limited to 'drivers/rtc/rtc-mrst.c')
-rw-r--r-- | drivers/rtc/rtc-mrst.c | 62 |
1 files changed, 16 insertions, 46 deletions
diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c index bcd0cf63eb1..b86bc328463 100644 --- a/drivers/rtc/rtc-mrst.c +++ b/drivers/rtc/rtc-mrst.c | |||
@@ -62,6 +62,17 @@ static inline int is_intr(u8 rtc_intr) | |||
62 | return rtc_intr & RTC_IRQMASK; | 62 | return rtc_intr & RTC_IRQMASK; |
63 | } | 63 | } |
64 | 64 | ||
65 | static inline unsigned char vrtc_is_updating(void) | ||
66 | { | ||
67 | unsigned char uip; | ||
68 | unsigned long flags; | ||
69 | |||
70 | spin_lock_irqsave(&rtc_lock, flags); | ||
71 | uip = (vrtc_cmos_read(RTC_FREQ_SELECT) & RTC_UIP); | ||
72 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
73 | return uip; | ||
74 | } | ||
75 | |||
65 | /* | 76 | /* |
66 | * rtc_time's year contains the increment over 1900, but vRTC's YEAR | 77 | * rtc_time's year contains the increment over 1900, but vRTC's YEAR |
67 | * register can't be programmed to value larger than 0x64, so vRTC | 78 | * register can't be programmed to value larger than 0x64, so vRTC |
@@ -76,7 +87,7 @@ static int mrst_read_time(struct device *dev, struct rtc_time *time) | |||
76 | { | 87 | { |
77 | unsigned long flags; | 88 | unsigned long flags; |
78 | 89 | ||
79 | if (rtc_is_updating()) | 90 | if (vrtc_is_updating()) |
80 | mdelay(20); | 91 | mdelay(20); |
81 | 92 | ||
82 | spin_lock_irqsave(&rtc_lock, flags); | 93 | spin_lock_irqsave(&rtc_lock, flags); |
@@ -236,61 +247,21 @@ static int mrst_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
236 | return 0; | 247 | return 0; |
237 | } | 248 | } |
238 | 249 | ||
239 | static int mrst_irq_set_state(struct device *dev, int enabled) | 250 | /* Currently, the vRTC doesn't support UIE ON/OFF */ |
251 | static int mrst_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | ||
240 | { | 252 | { |
241 | struct mrst_rtc *mrst = dev_get_drvdata(dev); | 253 | struct mrst_rtc *mrst = dev_get_drvdata(dev); |
242 | unsigned long flags; | 254 | unsigned long flags; |
243 | 255 | ||
244 | if (!mrst->irq) | ||
245 | return -ENXIO; | ||
246 | |||
247 | spin_lock_irqsave(&rtc_lock, flags); | 256 | spin_lock_irqsave(&rtc_lock, flags); |
248 | |||
249 | if (enabled) | 257 | if (enabled) |
250 | mrst_irq_enable(mrst, RTC_PIE); | 258 | mrst_irq_enable(mrst, RTC_AIE); |
251 | else | 259 | else |
252 | mrst_irq_disable(mrst, RTC_PIE); | ||
253 | |||
254 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | #if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE) | ||
259 | |||
260 | /* Currently, the vRTC doesn't support UIE ON/OFF */ | ||
261 | static int | ||
262 | mrst_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | ||
263 | { | ||
264 | struct mrst_rtc *mrst = dev_get_drvdata(dev); | ||
265 | unsigned long flags; | ||
266 | |||
267 | switch (cmd) { | ||
268 | case RTC_AIE_OFF: | ||
269 | case RTC_AIE_ON: | ||
270 | if (!mrst->irq) | ||
271 | return -EINVAL; | ||
272 | break; | ||
273 | default: | ||
274 | /* PIE ON/OFF is handled by mrst_irq_set_state() */ | ||
275 | return -ENOIOCTLCMD; | ||
276 | } | ||
277 | |||
278 | spin_lock_irqsave(&rtc_lock, flags); | ||
279 | switch (cmd) { | ||
280 | case RTC_AIE_OFF: /* alarm off */ | ||
281 | mrst_irq_disable(mrst, RTC_AIE); | 260 | mrst_irq_disable(mrst, RTC_AIE); |
282 | break; | ||
283 | case RTC_AIE_ON: /* alarm on */ | ||
284 | mrst_irq_enable(mrst, RTC_AIE); | ||
285 | break; | ||
286 | } | ||
287 | spin_unlock_irqrestore(&rtc_lock, flags); | 261 | spin_unlock_irqrestore(&rtc_lock, flags); |
288 | return 0; | 262 | return 0; |
289 | } | 263 | } |
290 | 264 | ||
291 | #else | ||
292 | #define mrst_rtc_ioctl NULL | ||
293 | #endif | ||
294 | 265 | ||
295 | #if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE) | 266 | #if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE) |
296 | 267 | ||
@@ -317,13 +288,12 @@ static int mrst_procfs(struct device *dev, struct seq_file *seq) | |||
317 | #endif | 288 | #endif |
318 | 289 | ||
319 | static const struct rtc_class_ops mrst_rtc_ops = { | 290 | static const struct rtc_class_ops mrst_rtc_ops = { |
320 | .ioctl = mrst_rtc_ioctl, | ||
321 | .read_time = mrst_read_time, | 291 | .read_time = mrst_read_time, |
322 | .set_time = mrst_set_time, | 292 | .set_time = mrst_set_time, |
323 | .read_alarm = mrst_read_alarm, | 293 | .read_alarm = mrst_read_alarm, |
324 | .set_alarm = mrst_set_alarm, | 294 | .set_alarm = mrst_set_alarm, |
325 | .proc = mrst_procfs, | 295 | .proc = mrst_procfs, |
326 | .irq_set_state = mrst_irq_set_state, | 296 | .alarm_irq_enable = mrst_rtc_alarm_irq_enable, |
327 | }; | 297 | }; |
328 | 298 | ||
329 | static struct mrst_rtc mrst_rtc; | 299 | static struct mrst_rtc mrst_rtc; |