RTC/watchdog: M41T80: fix a potential use of unitialized data
[linux-2.6] / drivers / rtc / rtc-m41t80.c
1 /*
2  * I2C client/driver for the ST M41T80 family of i2c rtc chips.
3  *
4  * Author: Alexander Bigga <ab@mycable.de>
5  *
6  * Based on m41t00.c by Mark A. Greer <mgreer@mvista.com>
7  *
8  * 2006 (c) mycable GmbH
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  *
14  */
15
16 #include <linux/module.h>
17 #include <linux/init.h>
18 #include <linux/slab.h>
19 #include <linux/string.h>
20 #include <linux/i2c.h>
21 #include <linux/rtc.h>
22 #include <linux/bcd.h>
23 #ifdef CONFIG_RTC_DRV_M41T80_WDT
24 #include <linux/miscdevice.h>
25 #include <linux/watchdog.h>
26 #include <linux/reboot.h>
27 #include <linux/fs.h>
28 #include <linux/ioctl.h>
29 #endif
30
31 #define M41T80_REG_SSEC 0
32 #define M41T80_REG_SEC  1
33 #define M41T80_REG_MIN  2
34 #define M41T80_REG_HOUR 3
35 #define M41T80_REG_WDAY 4
36 #define M41T80_REG_DAY  5
37 #define M41T80_REG_MON  6
38 #define M41T80_REG_YEAR 7
39 #define M41T80_REG_ALARM_MON    0xa
40 #define M41T80_REG_ALARM_DAY    0xb
41 #define M41T80_REG_ALARM_HOUR   0xc
42 #define M41T80_REG_ALARM_MIN    0xd
43 #define M41T80_REG_ALARM_SEC    0xe
44 #define M41T80_REG_FLAGS        0xf
45 #define M41T80_REG_SQW  0x13
46
47 #define M41T80_DATETIME_REG_SIZE        (M41T80_REG_YEAR + 1)
48 #define M41T80_ALARM_REG_SIZE   \
49         (M41T80_REG_ALARM_SEC + 1 - M41T80_REG_ALARM_MON)
50
51 #define M41T80_SEC_ST           (1 << 7)        /* ST: Stop Bit */
52 #define M41T80_ALMON_AFE        (1 << 7)        /* AFE: AF Enable Bit */
53 #define M41T80_ALMON_SQWE       (1 << 6)        /* SQWE: SQW Enable Bit */
54 #define M41T80_ALHOUR_HT        (1 << 6)        /* HT: Halt Update Bit */
55 #define M41T80_FLAGS_AF         (1 << 6)        /* AF: Alarm Flag Bit */
56 #define M41T80_FLAGS_BATT_LOW   (1 << 4)        /* BL: Battery Low Bit */
57
58 #define M41T80_FEATURE_HT       (1 << 0)
59 #define M41T80_FEATURE_BL       (1 << 1)
60
61 #define DRV_VERSION "0.05"
62
63 static const struct i2c_device_id m41t80_id[] = {
64         { "m41t80", 0 },
65         { "m41t81", M41T80_FEATURE_HT },
66         { "m41t81s", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
67         { "m41t82", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
68         { "m41t83", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
69         { "m41st84", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
70         { "m41st85", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
71         { "m41st87", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
72         { }
73 };
74 MODULE_DEVICE_TABLE(i2c, m41t80_id);
75
76 struct m41t80_data {
77         u8 features;
78         struct rtc_device *rtc;
79 };
80
81 static int m41t80_get_datetime(struct i2c_client *client,
82                                struct rtc_time *tm)
83 {
84         u8 buf[M41T80_DATETIME_REG_SIZE], dt_addr[1] = { M41T80_REG_SEC };
85         struct i2c_msg msgs[] = {
86                 {
87                         .addr   = client->addr,
88                         .flags  = 0,
89                         .len    = 1,
90                         .buf    = dt_addr,
91                 },
92                 {
93                         .addr   = client->addr,
94                         .flags  = I2C_M_RD,
95                         .len    = M41T80_DATETIME_REG_SIZE - M41T80_REG_SEC,
96                         .buf    = buf + M41T80_REG_SEC,
97                 },
98         };
99
100         if (i2c_transfer(client->adapter, msgs, 2) < 0) {
101                 dev_err(&client->dev, "read error\n");
102                 return -EIO;
103         }
104
105         tm->tm_sec = BCD2BIN(buf[M41T80_REG_SEC] & 0x7f);
106         tm->tm_min = BCD2BIN(buf[M41T80_REG_MIN] & 0x7f);
107         tm->tm_hour = BCD2BIN(buf[M41T80_REG_HOUR] & 0x3f);
108         tm->tm_mday = BCD2BIN(buf[M41T80_REG_DAY] & 0x3f);
109         tm->tm_wday = buf[M41T80_REG_WDAY] & 0x07;
110         tm->tm_mon = BCD2BIN(buf[M41T80_REG_MON] & 0x1f) - 1;
111
112         /* assume 20YY not 19YY, and ignore the Century Bit */
113         tm->tm_year = BCD2BIN(buf[M41T80_REG_YEAR]) + 100;
114         return 0;
115 }
116
117 /* Sets the given date and time to the real time clock. */
118 static int m41t80_set_datetime(struct i2c_client *client, struct rtc_time *tm)
119 {
120         u8 wbuf[1 + M41T80_DATETIME_REG_SIZE];
121         u8 *buf = &wbuf[1];
122         u8 dt_addr[1] = { M41T80_REG_SEC };
123         struct i2c_msg msgs_in[] = {
124                 {
125                         .addr   = client->addr,
126                         .flags  = 0,
127                         .len    = 1,
128                         .buf    = dt_addr,
129                 },
130                 {
131                         .addr   = client->addr,
132                         .flags  = I2C_M_RD,
133                         .len    = M41T80_DATETIME_REG_SIZE - M41T80_REG_SEC,
134                         .buf    = buf + M41T80_REG_SEC,
135                 },
136         };
137         struct i2c_msg msgs[] = {
138                 {
139                         .addr   = client->addr,
140                         .flags  = 0,
141                         .len    = 1 + M41T80_DATETIME_REG_SIZE,
142                         .buf    = wbuf,
143                  },
144         };
145
146         /* Read current reg values into buf[1..7] */
147         if (i2c_transfer(client->adapter, msgs_in, 2) < 0) {
148                 dev_err(&client->dev, "read error\n");
149                 return -EIO;
150         }
151
152         wbuf[0] = 0; /* offset into rtc's regs */
153         /* Merge time-data and register flags into buf[0..7] */
154         buf[M41T80_REG_SSEC] = 0;
155         buf[M41T80_REG_SEC] =
156                 BIN2BCD(tm->tm_sec) | (buf[M41T80_REG_SEC] & ~0x7f);
157         buf[M41T80_REG_MIN] =
158                 BIN2BCD(tm->tm_min) | (buf[M41T80_REG_MIN] & ~0x7f);
159         buf[M41T80_REG_HOUR] =
160                 BIN2BCD(tm->tm_hour) | (buf[M41T80_REG_HOUR] & ~0x3f) ;
161         buf[M41T80_REG_WDAY] =
162                 (tm->tm_wday & 0x07) | (buf[M41T80_REG_WDAY] & ~0x07);
163         buf[M41T80_REG_DAY] =
164                 BIN2BCD(tm->tm_mday) | (buf[M41T80_REG_DAY] & ~0x3f);
165         buf[M41T80_REG_MON] =
166                 BIN2BCD(tm->tm_mon + 1) | (buf[M41T80_REG_MON] & ~0x1f);
167         /* assume 20YY not 19YY */
168         buf[M41T80_REG_YEAR] = BIN2BCD(tm->tm_year % 100);
169
170         if (i2c_transfer(client->adapter, msgs, 1) != 1) {
171                 dev_err(&client->dev, "write error\n");
172                 return -EIO;
173         }
174         return 0;
175 }
176
177 #if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE)
178 static int m41t80_rtc_proc(struct device *dev, struct seq_file *seq)
179 {
180         struct i2c_client *client = to_i2c_client(dev);
181         struct m41t80_data *clientdata = i2c_get_clientdata(client);
182         u8 reg;
183
184         if (clientdata->features & M41T80_FEATURE_BL) {
185                 reg = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
186                 seq_printf(seq, "battery\t\t: %s\n",
187                            (reg & M41T80_FLAGS_BATT_LOW) ? "exhausted" : "ok");
188         }
189         return 0;
190 }
191 #else
192 #define m41t80_rtc_proc NULL
193 #endif
194
195 static int m41t80_rtc_read_time(struct device *dev, struct rtc_time *tm)
196 {
197         return m41t80_get_datetime(to_i2c_client(dev), tm);
198 }
199
200 static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm)
201 {
202         return m41t80_set_datetime(to_i2c_client(dev), tm);
203 }
204
205 #if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE)
206 static int
207 m41t80_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
208 {
209         struct i2c_client *client = to_i2c_client(dev);
210         int rc;
211
212         switch (cmd) {
213         case RTC_AIE_OFF:
214         case RTC_AIE_ON:
215                 break;
216         default:
217                 return -ENOIOCTLCMD;
218         }
219
220         rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
221         if (rc < 0)
222                 goto err;
223         switch (cmd) {
224         case RTC_AIE_OFF:
225                 rc &= ~M41T80_ALMON_AFE;
226                 break;
227         case RTC_AIE_ON:
228                 rc |= M41T80_ALMON_AFE;
229                 break;
230         }
231         if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, rc) < 0)
232                 goto err;
233         return 0;
234 err:
235         return -EIO;
236 }
237 #else
238 #define m41t80_rtc_ioctl NULL
239 #endif
240
241 static int m41t80_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t)
242 {
243         struct i2c_client *client = to_i2c_client(dev);
244         u8 wbuf[1 + M41T80_ALARM_REG_SIZE];
245         u8 *buf = &wbuf[1];
246         u8 *reg = buf - M41T80_REG_ALARM_MON;
247         u8 dt_addr[1] = { M41T80_REG_ALARM_MON };
248         struct i2c_msg msgs_in[] = {
249                 {
250                         .addr   = client->addr,
251                         .flags  = 0,
252                         .len    = 1,
253                         .buf    = dt_addr,
254                 },
255                 {
256                         .addr   = client->addr,
257                         .flags  = I2C_M_RD,
258                         .len    = M41T80_ALARM_REG_SIZE,
259                         .buf    = buf,
260                 },
261         };
262         struct i2c_msg msgs[] = {
263                 {
264                         .addr   = client->addr,
265                         .flags  = 0,
266                         .len    = 1 + M41T80_ALARM_REG_SIZE,
267                         .buf    = wbuf,
268                  },
269         };
270
271         if (i2c_transfer(client->adapter, msgs_in, 2) < 0) {
272                 dev_err(&client->dev, "read error\n");
273                 return -EIO;
274         }
275         reg[M41T80_REG_ALARM_MON] &= ~(0x1f | M41T80_ALMON_AFE);
276         reg[M41T80_REG_ALARM_DAY] = 0;
277         reg[M41T80_REG_ALARM_HOUR] &= ~(0x3f | 0x80);
278         reg[M41T80_REG_ALARM_MIN] = 0;
279         reg[M41T80_REG_ALARM_SEC] = 0;
280
281         wbuf[0] = M41T80_REG_ALARM_MON; /* offset into rtc's regs */
282         reg[M41T80_REG_ALARM_SEC] |= t->time.tm_sec >= 0 ?
283                 BIN2BCD(t->time.tm_sec) : 0x80;
284         reg[M41T80_REG_ALARM_MIN] |= t->time.tm_min >= 0 ?
285                 BIN2BCD(t->time.tm_min) : 0x80;
286         reg[M41T80_REG_ALARM_HOUR] |= t->time.tm_hour >= 0 ?
287                 BIN2BCD(t->time.tm_hour) : 0x80;
288         reg[M41T80_REG_ALARM_DAY] |= t->time.tm_mday >= 0 ?
289                 BIN2BCD(t->time.tm_mday) : 0x80;
290         if (t->time.tm_mon >= 0)
291                 reg[M41T80_REG_ALARM_MON] |= BIN2BCD(t->time.tm_mon + 1);
292         else
293                 reg[M41T80_REG_ALARM_DAY] |= 0x40;
294
295         if (i2c_transfer(client->adapter, msgs, 1) != 1) {
296                 dev_err(&client->dev, "write error\n");
297                 return -EIO;
298         }
299
300         if (t->enabled) {
301                 reg[M41T80_REG_ALARM_MON] |= M41T80_ALMON_AFE;
302                 if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
303                                               reg[M41T80_REG_ALARM_MON]) < 0) {
304                         dev_err(&client->dev, "write error\n");
305                         return -EIO;
306                 }
307         }
308         return 0;
309 }
310
311 static int m41t80_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *t)
312 {
313         struct i2c_client *client = to_i2c_client(dev);
314         u8 buf[M41T80_ALARM_REG_SIZE + 1]; /* all alarm regs and flags */
315         u8 dt_addr[1] = { M41T80_REG_ALARM_MON };
316         u8 *reg = buf - M41T80_REG_ALARM_MON;
317         struct i2c_msg msgs[] = {
318                 {
319                         .addr   = client->addr,
320                         .flags  = 0,
321                         .len    = 1,
322                         .buf    = dt_addr,
323                 },
324                 {
325                         .addr   = client->addr,
326                         .flags  = I2C_M_RD,
327                         .len    = M41T80_ALARM_REG_SIZE + 1,
328                         .buf    = buf,
329                 },
330         };
331
332         if (i2c_transfer(client->adapter, msgs, 2) < 0) {
333                 dev_err(&client->dev, "read error\n");
334                 return -EIO;
335         }
336         t->time.tm_sec = -1;
337         t->time.tm_min = -1;
338         t->time.tm_hour = -1;
339         t->time.tm_mday = -1;
340         t->time.tm_mon = -1;
341         if (!(reg[M41T80_REG_ALARM_SEC] & 0x80))
342                 t->time.tm_sec = BCD2BIN(reg[M41T80_REG_ALARM_SEC] & 0x7f);
343         if (!(reg[M41T80_REG_ALARM_MIN] & 0x80))
344                 t->time.tm_min = BCD2BIN(reg[M41T80_REG_ALARM_MIN] & 0x7f);
345         if (!(reg[M41T80_REG_ALARM_HOUR] & 0x80))
346                 t->time.tm_hour = BCD2BIN(reg[M41T80_REG_ALARM_HOUR] & 0x3f);
347         if (!(reg[M41T80_REG_ALARM_DAY] & 0x80))
348                 t->time.tm_mday = BCD2BIN(reg[M41T80_REG_ALARM_DAY] & 0x3f);
349         if (!(reg[M41T80_REG_ALARM_DAY] & 0x40))
350                 t->time.tm_mon = BCD2BIN(reg[M41T80_REG_ALARM_MON] & 0x1f) - 1;
351         t->time.tm_year = -1;
352         t->time.tm_wday = -1;
353         t->time.tm_yday = -1;
354         t->time.tm_isdst = -1;
355         t->enabled = !!(reg[M41T80_REG_ALARM_MON] & M41T80_ALMON_AFE);
356         t->pending = !!(reg[M41T80_REG_FLAGS] & M41T80_FLAGS_AF);
357         return 0;
358 }
359
360 static struct rtc_class_ops m41t80_rtc_ops = {
361         .read_time = m41t80_rtc_read_time,
362         .set_time = m41t80_rtc_set_time,
363         .read_alarm = m41t80_rtc_read_alarm,
364         .set_alarm = m41t80_rtc_set_alarm,
365         .proc = m41t80_rtc_proc,
366         .ioctl = m41t80_rtc_ioctl,
367 };
368
369 #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE)
370 static ssize_t m41t80_sysfs_show_flags(struct device *dev,
371                                 struct device_attribute *attr, char *buf)
372 {
373         struct i2c_client *client = to_i2c_client(dev);
374         int val;
375
376         val = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
377         if (val < 0)
378                 return -EIO;
379         return sprintf(buf, "%#x\n", val);
380 }
381 static DEVICE_ATTR(flags, S_IRUGO, m41t80_sysfs_show_flags, NULL);
382
383 static ssize_t m41t80_sysfs_show_sqwfreq(struct device *dev,
384                                 struct device_attribute *attr, char *buf)
385 {
386         struct i2c_client *client = to_i2c_client(dev);
387         int val;
388
389         val = i2c_smbus_read_byte_data(client, M41T80_REG_SQW);
390         if (val < 0)
391                 return -EIO;
392         val = (val >> 4) & 0xf;
393         switch (val) {
394         case 0:
395                 break;
396         case 1:
397                 val = 32768;
398                 break;
399         default:
400                 val = 32768 >> val;
401         }
402         return sprintf(buf, "%d\n", val);
403 }
404 static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev,
405                                 struct device_attribute *attr,
406                                 const char *buf, size_t count)
407 {
408         struct i2c_client *client = to_i2c_client(dev);
409         int almon, sqw;
410         int val = simple_strtoul(buf, NULL, 0);
411
412         if (val) {
413                 if (!is_power_of_2(val))
414                         return -EINVAL;
415                 val = ilog2(val);
416                 if (val == 15)
417                         val = 1;
418                 else if (val < 14)
419                         val = 15 - val;
420                 else
421                         return -EINVAL;
422         }
423         /* disable SQW, set SQW frequency & re-enable */
424         almon = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
425         if (almon < 0)
426                 return -EIO;
427         sqw = i2c_smbus_read_byte_data(client, M41T80_REG_SQW);
428         if (sqw < 0)
429                 return -EIO;
430         sqw = (sqw & 0x0f) | (val << 4);
431         if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
432                                       almon & ~M41T80_ALMON_SQWE) < 0 ||
433             i2c_smbus_write_byte_data(client, M41T80_REG_SQW, sqw) < 0)
434                 return -EIO;
435         if (val && i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
436                                              almon | M41T80_ALMON_SQWE) < 0)
437                 return -EIO;
438         return count;
439 }
440 static DEVICE_ATTR(sqwfreq, S_IRUGO | S_IWUSR,
441                    m41t80_sysfs_show_sqwfreq, m41t80_sysfs_set_sqwfreq);
442
443 static struct attribute *attrs[] = {
444         &dev_attr_flags.attr,
445         &dev_attr_sqwfreq.attr,
446         NULL,
447 };
448 static struct attribute_group attr_group = {
449         .attrs = attrs,
450 };
451
452 static int m41t80_sysfs_register(struct device *dev)
453 {
454         return sysfs_create_group(&dev->kobj, &attr_group);
455 }
456 #else
457 static int m41t80_sysfs_register(struct device *dev)
458 {
459         return 0;
460 }
461 #endif
462
463 #ifdef CONFIG_RTC_DRV_M41T80_WDT
464 /*
465  *****************************************************************************
466  *
467  * Watchdog Driver
468  *
469  *****************************************************************************
470  */
471 static struct i2c_client *save_client;
472
473 /* Default margin */
474 #define WD_TIMO 60              /* 1..31 seconds */
475
476 static int wdt_margin = WD_TIMO;
477 module_param(wdt_margin, int, 0);
478 MODULE_PARM_DESC(wdt_margin, "Watchdog timeout in seconds (default 60s)");
479
480 static unsigned long wdt_is_open;
481 static int boot_flag;
482
483 /**
484  *      wdt_ping:
485  *
486  *      Reload counter one with the watchdog timeout. We don't bother reloading
487  *      the cascade counter.
488  */
489 static void wdt_ping(void)
490 {
491         unsigned char i2c_data[2];
492         struct i2c_msg msgs1[1] = {
493                 {
494                         .addr   = save_client->addr,
495                         .flags  = 0,
496                         .len    = 2,
497                         .buf    = i2c_data,
498                 },
499         };
500         i2c_data[0] = 0x09;             /* watchdog register */
501
502         if (wdt_margin > 31)
503                 i2c_data[1] = (wdt_margin & 0xFC) | 0x83; /* resolution = 4s */
504         else
505                 /*
506                  * WDS = 1 (0x80), mulitplier = WD_TIMO, resolution = 1s (0x02)
507                  */
508                 i2c_data[1] = wdt_margin<<2 | 0x82;
509
510         i2c_transfer(save_client->adapter, msgs1, 1);
511 }
512
513 /**
514  *      wdt_disable:
515  *
516  *      disables watchdog.
517  */
518 static void wdt_disable(void)
519 {
520         unsigned char i2c_data[2], i2c_buf[0x10];
521         struct i2c_msg msgs0[2] = {
522                 {
523                         .addr   = save_client->addr,
524                         .flags  = 0,
525                         .len    = 1,
526                         .buf    = i2c_data,
527                 },
528                 {
529                         .addr   = save_client->addr,
530                         .flags  = I2C_M_RD,
531                         .len    = 1,
532                         .buf    = i2c_buf,
533                 },
534         };
535         struct i2c_msg msgs1[1] = {
536                 {
537                         .addr   = save_client->addr,
538                         .flags  = 0,
539                         .len    = 2,
540                         .buf    = i2c_data,
541                 },
542         };
543
544         i2c_data[0] = 0x09;
545         i2c_transfer(save_client->adapter, msgs0, 2);
546
547         i2c_data[0] = 0x09;
548         i2c_data[1] = 0x00;
549         i2c_transfer(save_client->adapter, msgs1, 1);
550 }
551
552 /**
553  *      wdt_write:
554  *      @file: file handle to the watchdog
555  *      @buf: buffer to write (unused as data does not matter here
556  *      @count: count of bytes
557  *      @ppos: pointer to the position to write. No seeks allowed
558  *
559  *      A write to a watchdog device is defined as a keepalive signal. Any
560  *      write of data will do, as we we don't define content meaning.
561  */
562 static ssize_t wdt_write(struct file *file, const char __user *buf,
563                          size_t count, loff_t *ppos)
564 {
565         /*  Can't seek (pwrite) on this device
566         if (ppos != &file->f_pos)
567         return -ESPIPE;
568         */
569         if (count) {
570                 wdt_ping();
571                 return 1;
572         }
573         return 0;
574 }
575
576 static ssize_t wdt_read(struct file *file, char __user *buf,
577                         size_t count, loff_t *ppos)
578 {
579         return 0;
580 }
581
582 /**
583  *      wdt_ioctl:
584  *      @inode: inode of the device
585  *      @file: file handle to the device
586  *      @cmd: watchdog command
587  *      @arg: argument pointer
588  *
589  *      The watchdog API defines a common set of functions for all watchdogs
590  *      according to their available features. We only actually usefully support
591  *      querying capabilities and current status.
592  */
593 static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
594                      unsigned long arg)
595 {
596         int new_margin, rv;
597         static struct watchdog_info ident = {
598                 .options = WDIOF_POWERUNDER | WDIOF_KEEPALIVEPING |
599                         WDIOF_SETTIMEOUT,
600                 .firmware_version = 1,
601                 .identity = "M41T80 WTD"
602         };
603
604         switch (cmd) {
605         case WDIOC_GETSUPPORT:
606                 return copy_to_user((struct watchdog_info __user *)arg, &ident,
607                                     sizeof(ident)) ? -EFAULT : 0;
608
609         case WDIOC_GETSTATUS:
610         case WDIOC_GETBOOTSTATUS:
611                 return put_user(boot_flag, (int __user *)arg);
612         case WDIOC_KEEPALIVE:
613                 wdt_ping();
614                 return 0;
615         case WDIOC_SETTIMEOUT:
616                 if (get_user(new_margin, (int __user *)arg))
617                         return -EFAULT;
618                 /* Arbitrary, can't find the card's limits */
619                 if (new_margin < 1 || new_margin > 124)
620                         return -EINVAL;
621                 wdt_margin = new_margin;
622                 wdt_ping();
623                 /* Fall */
624         case WDIOC_GETTIMEOUT:
625                 return put_user(wdt_margin, (int __user *)arg);
626
627         case WDIOC_SETOPTIONS:
628                 if (copy_from_user(&rv, (int __user *)arg, sizeof(int)))
629                         return -EFAULT;
630
631                 if (rv & WDIOS_DISABLECARD) {
632                         printk(KERN_INFO
633                                "rtc-m41t80: disable watchdog\n");
634                         wdt_disable();
635                 }
636
637                 if (rv & WDIOS_ENABLECARD) {
638                         printk(KERN_INFO
639                                "rtc-m41t80: enable watchdog\n");
640                         wdt_ping();
641                 }
642
643                 return -EINVAL;
644         }
645         return -ENOTTY;
646 }
647
648 /**
649  *      wdt_open:
650  *      @inode: inode of device
651  *      @file: file handle to device
652  *
653  */
654 static int wdt_open(struct inode *inode, struct file *file)
655 {
656         if (MINOR(inode->i_rdev) == WATCHDOG_MINOR) {
657                 if (test_and_set_bit(0, &wdt_is_open))
658                         return -EBUSY;
659                 /*
660                  *      Activate
661                  */
662                 wdt_is_open = 1;
663                 return 0;
664         }
665         return -ENODEV;
666 }
667
668 /**
669  *      wdt_close:
670  *      @inode: inode to board
671  *      @file: file handle to board
672  *
673  */
674 static int wdt_release(struct inode *inode, struct file *file)
675 {
676         if (MINOR(inode->i_rdev) == WATCHDOG_MINOR)
677                 clear_bit(0, &wdt_is_open);
678         return 0;
679 }
680
681 /**
682  *      notify_sys:
683  *      @this: our notifier block
684  *      @code: the event being reported
685  *      @unused: unused
686  *
687  *      Our notifier is called on system shutdowns. We want to turn the card
688  *      off at reboot otherwise the machine will reboot again during memory
689  *      test or worse yet during the following fsck. This would suck, in fact
690  *      trust me - if it happens it does suck.
691  */
692 static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
693                           void *unused)
694 {
695         if (code == SYS_DOWN || code == SYS_HALT)
696                 /* Disable Watchdog */
697                 wdt_disable();
698         return NOTIFY_DONE;
699 }
700
701 static const struct file_operations wdt_fops = {
702         .owner  = THIS_MODULE,
703         .read   = wdt_read,
704         .ioctl  = wdt_ioctl,
705         .write  = wdt_write,
706         .open   = wdt_open,
707         .release = wdt_release,
708 };
709
710 static struct miscdevice wdt_dev = {
711         .minor = WATCHDOG_MINOR,
712         .name = "watchdog",
713         .fops = &wdt_fops,
714 };
715
716 /*
717  *      The WDT card needs to learn about soft shutdowns in order to
718  *      turn the timebomb registers off.
719  */
720 static struct notifier_block wdt_notifier = {
721         .notifier_call = wdt_notify_sys,
722 };
723 #endif /* CONFIG_RTC_DRV_M41T80_WDT */
724
725 /*
726  *****************************************************************************
727  *
728  *      Driver Interface
729  *
730  *****************************************************************************
731  */
732 static int m41t80_probe(struct i2c_client *client,
733                         const struct i2c_device_id *id)
734 {
735         int rc = 0;
736         struct rtc_device *rtc = NULL;
737         struct rtc_time tm;
738         struct m41t80_data *clientdata = NULL;
739
740         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C
741                                      | I2C_FUNC_SMBUS_BYTE_DATA)) {
742                 rc = -ENODEV;
743                 goto exit;
744         }
745
746         dev_info(&client->dev,
747                  "chip found, driver version " DRV_VERSION "\n");
748
749         clientdata = kzalloc(sizeof(*clientdata), GFP_KERNEL);
750         if (!clientdata) {
751                 rc = -ENOMEM;
752                 goto exit;
753         }
754
755         rtc = rtc_device_register(client->name, &client->dev,
756                                   &m41t80_rtc_ops, THIS_MODULE);
757         if (IS_ERR(rtc)) {
758                 rc = PTR_ERR(rtc);
759                 rtc = NULL;
760                 goto exit;
761         }
762
763         clientdata->rtc = rtc;
764         clientdata->features = id->driver_data;
765         i2c_set_clientdata(client, clientdata);
766
767         /* Make sure HT (Halt Update) bit is cleared */
768         rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_HOUR);
769         if (rc < 0)
770                 goto ht_err;
771
772         if (rc & M41T80_ALHOUR_HT) {
773                 if (clientdata->features & M41T80_FEATURE_HT) {
774                         m41t80_get_datetime(client, &tm);
775                         dev_info(&client->dev, "HT bit was set!\n");
776                         dev_info(&client->dev,
777                                  "Power Down at "
778                                  "%04i-%02i-%02i %02i:%02i:%02i\n",
779                                  tm.tm_year + 1900,
780                                  tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
781                                  tm.tm_min, tm.tm_sec);
782                 }
783                 if (i2c_smbus_write_byte_data(client,
784                                               M41T80_REG_ALARM_HOUR,
785                                               rc & ~M41T80_ALHOUR_HT) < 0)
786                         goto ht_err;
787         }
788
789         /* Make sure ST (stop) bit is cleared */
790         rc = i2c_smbus_read_byte_data(client, M41T80_REG_SEC);
791         if (rc < 0)
792                 goto st_err;
793
794         if (rc & M41T80_SEC_ST) {
795                 if (i2c_smbus_write_byte_data(client, M41T80_REG_SEC,
796                                               rc & ~M41T80_SEC_ST) < 0)
797                         goto st_err;
798         }
799
800         rc = m41t80_sysfs_register(&client->dev);
801         if (rc)
802                 goto exit;
803
804 #ifdef CONFIG_RTC_DRV_M41T80_WDT
805         if (clientdata->features & M41T80_FEATURE_HT) {
806                 save_client = client;
807                 rc = misc_register(&wdt_dev);
808                 if (rc)
809                         goto exit;
810                 rc = register_reboot_notifier(&wdt_notifier);
811                 if (rc) {
812                         misc_deregister(&wdt_dev);
813                         goto exit;
814                 }
815         }
816 #endif
817         return 0;
818
819 st_err:
820         rc = -EIO;
821         dev_err(&client->dev, "Can't clear ST bit\n");
822         goto exit;
823 ht_err:
824         rc = -EIO;
825         dev_err(&client->dev, "Can't clear HT bit\n");
826         goto exit;
827
828 exit:
829         if (rtc)
830                 rtc_device_unregister(rtc);
831         kfree(clientdata);
832         return rc;
833 }
834
835 static int m41t80_remove(struct i2c_client *client)
836 {
837         struct m41t80_data *clientdata = i2c_get_clientdata(client);
838         struct rtc_device *rtc = clientdata->rtc;
839
840 #ifdef CONFIG_RTC_DRV_M41T80_WDT
841         if (clientdata->features & M41T80_FEATURE_HT) {
842                 misc_deregister(&wdt_dev);
843                 unregister_reboot_notifier(&wdt_notifier);
844         }
845 #endif
846         if (rtc)
847                 rtc_device_unregister(rtc);
848         kfree(clientdata);
849
850         return 0;
851 }
852
853 static struct i2c_driver m41t80_driver = {
854         .driver = {
855                 .name = "rtc-m41t80",
856         },
857         .probe = m41t80_probe,
858         .remove = m41t80_remove,
859         .id_table = m41t80_id,
860 };
861
862 static int __init m41t80_rtc_init(void)
863 {
864         return i2c_add_driver(&m41t80_driver);
865 }
866
867 static void __exit m41t80_rtc_exit(void)
868 {
869         i2c_del_driver(&m41t80_driver);
870 }
871
872 MODULE_AUTHOR("Alexander Bigga <ab@mycable.de>");
873 MODULE_DESCRIPTION("ST Microelectronics M41T80 series RTC I2C Client Driver");
874 MODULE_LICENSE("GPL");
875 MODULE_VERSION(DRV_VERSION);
876
877 module_init(m41t80_rtc_init);
878 module_exit(m41t80_rtc_exit);