aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-mrst.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-mrst.c')
-rw-r--r--drivers/rtc/rtc-mrst.c62
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
65static 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
239static int mrst_irq_set_state(struct device *dev, int enabled) 250/* Currently, the vRTC doesn't support UIE ON/OFF */
251static 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 */
261static int
262mrst_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
319static const struct rtc_class_ops mrst_rtc_ops = { 290static 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
329static struct mrst_rtc mrst_rtc; 299static struct mrst_rtc mrst_rtc;