diff options
author | Rodolfo Giometti <giometti@linux.it> | 2008-10-16 01:02:58 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-16 14:21:39 -0400 |
commit | cb49a5e9ee4fb0ab6a84a29c4de6c1bd112d38df (patch) | |
tree | 98296a1d7b1d9d0d7b7d152180f92cdbf600051d | |
parent | 2f9b75e09ec3f62f2ebecec0ac9aec58656c2459 (diff) |
rtc-ds1307: alarm support for ds1337/ds1339
Update the ds1307 driver with alarm support for ds1337/ds1339. This uses
the first alarm (there are two), and matches on seconds, minutes, hours,
and day-of-month. Tested on ds1339.
[dbrownell@users.sourceforge.net: add comments; fixup style, valid irq
checks, debug dumps; lock; more careful IRQ shutdown; switch BCD2BIN to
bcd2bin (and vice versa); ENOTTY not EINVAL.]
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Rodolfo Giometti <giometti@linux.it>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/rtc/rtc-ds1307.c | 308 |
1 files changed, 295 insertions, 13 deletions
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index bbf97e65202a..4fcf0734a6ef 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c | |||
@@ -23,10 +23,6 @@ | |||
23 | * to have set the chip up as a clock (turning on the oscillator and | 23 | * to have set the chip up as a clock (turning on the oscillator and |
24 | * setting the date and time), Linux can ignore the non-clock features. | 24 | * setting the date and time), Linux can ignore the non-clock features. |
25 | * That's a natural job for a factory or repair bench. | 25 | * That's a natural job for a factory or repair bench. |
26 | * | ||
27 | * This is currently a simple no-alarms driver. If your board has the | ||
28 | * alarm irq wired up on a ds1337 or ds1339, and you want to use that, | ||
29 | * then look at the rtc-rs5c372 driver for code to steal... | ||
30 | */ | 26 | */ |
31 | enum ds_type { | 27 | enum ds_type { |
32 | ds_1307, | 28 | ds_1307, |
@@ -67,6 +63,7 @@ enum ds_type { | |||
67 | # define DS1307_BIT_RS0 0x01 | 63 | # define DS1307_BIT_RS0 0x01 |
68 | #define DS1337_REG_CONTROL 0x0e | 64 | #define DS1337_REG_CONTROL 0x0e |
69 | # define DS1337_BIT_nEOSC 0x80 | 65 | # define DS1337_BIT_nEOSC 0x80 |
66 | # define DS1339_BIT_BBSQI 0x20 | ||
70 | # define DS1337_BIT_RS2 0x10 | 67 | # define DS1337_BIT_RS2 0x10 |
71 | # define DS1337_BIT_RS1 0x08 | 68 | # define DS1337_BIT_RS1 0x08 |
72 | # define DS1337_BIT_INTCN 0x04 | 69 | # define DS1337_BIT_INTCN 0x04 |
@@ -83,19 +80,22 @@ enum ds_type { | |||
83 | # define DS1337_BIT_OSF 0x80 | 80 | # define DS1337_BIT_OSF 0x80 |
84 | # define DS1337_BIT_A2I 0x02 | 81 | # define DS1337_BIT_A2I 0x02 |
85 | # define DS1337_BIT_A1I 0x01 | 82 | # define DS1337_BIT_A1I 0x01 |
83 | #define DS1339_REG_ALARM1_SECS 0x07 | ||
86 | #define DS1339_REG_TRICKLE 0x10 | 84 | #define DS1339_REG_TRICKLE 0x10 |
87 | 85 | ||
88 | 86 | ||
89 | 87 | ||
90 | struct ds1307 { | 88 | struct ds1307 { |
91 | u8 reg_addr; | 89 | u8 reg_addr; |
92 | bool has_nvram; | 90 | u8 regs[11]; |
93 | u8 regs[8]; | ||
94 | enum ds_type type; | 91 | enum ds_type type; |
92 | unsigned long flags; | ||
93 | #define HAS_NVRAM 0 /* bit 0 == sysfs file active */ | ||
94 | #define HAS_ALARM 1 /* bit 1 == irq claimed */ | ||
95 | struct i2c_msg msg[2]; | 95 | struct i2c_msg msg[2]; |
96 | struct i2c_client *client; | 96 | struct i2c_client *client; |
97 | struct i2c_client dev; | ||
98 | struct rtc_device *rtc; | 97 | struct rtc_device *rtc; |
98 | struct work_struct work; | ||
99 | }; | 99 | }; |
100 | 100 | ||
101 | struct chip_desc { | 101 | struct chip_desc { |
@@ -132,12 +132,79 @@ static const struct i2c_device_id ds1307_id[] = { | |||
132 | }; | 132 | }; |
133 | MODULE_DEVICE_TABLE(i2c, ds1307_id); | 133 | MODULE_DEVICE_TABLE(i2c, ds1307_id); |
134 | 134 | ||
135 | /*----------------------------------------------------------------------*/ | ||
136 | |||
137 | /* | ||
138 | * The IRQ logic includes a "real" handler running in IRQ context just | ||
139 | * long enough to schedule this workqueue entry. We need a task context | ||
140 | * to talk to the RTC, since I2C I/O calls require that; and disable the | ||
141 | * IRQ until we clear its status on the chip, so that this handler can | ||
142 | * work with any type of triggering (not just falling edge). | ||
143 | * | ||
144 | * The ds1337 and ds1339 both have two alarms, but we only use the first | ||
145 | * one (with a "seconds" field). For ds1337 we expect nINTA is our alarm | ||
146 | * signal; ds1339 chips have only one alarm signal. | ||
147 | */ | ||
148 | static void ds1307_work(struct work_struct *work) | ||
149 | { | ||
150 | struct ds1307 *ds1307; | ||
151 | struct i2c_client *client; | ||
152 | struct mutex *lock; | ||
153 | int stat, control; | ||
154 | |||
155 | ds1307 = container_of(work, struct ds1307, work); | ||
156 | client = ds1307->client; | ||
157 | lock = &ds1307->rtc->ops_lock; | ||
158 | |||
159 | mutex_lock(lock); | ||
160 | stat = i2c_smbus_read_byte_data(client, DS1337_REG_STATUS); | ||
161 | if (stat < 0) | ||
162 | goto out; | ||
163 | |||
164 | if (stat & DS1337_BIT_A1I) { | ||
165 | stat &= ~DS1337_BIT_A1I; | ||
166 | i2c_smbus_write_byte_data(client, DS1337_REG_STATUS, stat); | ||
167 | |||
168 | control = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL); | ||
169 | if (control < 0) | ||
170 | goto out; | ||
171 | |||
172 | control &= ~DS1337_BIT_A1IE; | ||
173 | i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, control); | ||
174 | |||
175 | /* rtc_update_irq() assumes that it is called | ||
176 | * from IRQ-disabled context. | ||
177 | */ | ||
178 | local_irq_disable(); | ||
179 | rtc_update_irq(ds1307->rtc, 1, RTC_AF | RTC_IRQF); | ||
180 | local_irq_enable(); | ||
181 | } | ||
182 | |||
183 | out: | ||
184 | if (test_bit(HAS_ALARM, &ds1307->flags)) | ||
185 | enable_irq(client->irq); | ||
186 | mutex_unlock(lock); | ||
187 | } | ||
188 | |||
189 | static irqreturn_t ds1307_irq(int irq, void *dev_id) | ||
190 | { | ||
191 | struct i2c_client *client = dev_id; | ||
192 | struct ds1307 *ds1307 = i2c_get_clientdata(client); | ||
193 | |||
194 | disable_irq_nosync(irq); | ||
195 | schedule_work(&ds1307->work); | ||
196 | return IRQ_HANDLED; | ||
197 | } | ||
198 | |||
199 | /*----------------------------------------------------------------------*/ | ||
200 | |||
135 | static int ds1307_get_time(struct device *dev, struct rtc_time *t) | 201 | static int ds1307_get_time(struct device *dev, struct rtc_time *t) |
136 | { | 202 | { |
137 | struct ds1307 *ds1307 = dev_get_drvdata(dev); | 203 | struct ds1307 *ds1307 = dev_get_drvdata(dev); |
138 | int tmp; | 204 | int tmp; |
139 | 205 | ||
140 | /* read the RTC date and time registers all at once */ | 206 | /* read the RTC date and time registers all at once */ |
207 | ds1307->reg_addr = 0; | ||
141 | ds1307->msg[1].flags = I2C_M_RD; | 208 | ds1307->msg[1].flags = I2C_M_RD; |
142 | ds1307->msg[1].len = 7; | 209 | ds1307->msg[1].len = 7; |
143 | 210 | ||
@@ -231,9 +298,186 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) | |||
231 | return 0; | 298 | return 0; |
232 | } | 299 | } |
233 | 300 | ||
301 | static int ds1307_read_alarm(struct device *dev, struct rtc_wkalrm *t) | ||
302 | { | ||
303 | struct i2c_client *client = to_i2c_client(dev); | ||
304 | struct ds1307 *ds1307 = i2c_get_clientdata(client); | ||
305 | int ret; | ||
306 | |||
307 | if (!test_bit(HAS_ALARM, &ds1307->flags)) | ||
308 | return -EINVAL; | ||
309 | |||
310 | /* read all ALARM1, ALARM2, and status registers at once */ | ||
311 | ds1307->reg_addr = DS1339_REG_ALARM1_SECS; | ||
312 | ds1307->msg[1].flags = I2C_M_RD; | ||
313 | ds1307->msg[1].len = 9; | ||
314 | |||
315 | ret = i2c_transfer(to_i2c_adapter(client->dev.parent), | ||
316 | ds1307->msg, 2); | ||
317 | if (ret != 2) { | ||
318 | dev_err(dev, "%s error %d\n", "alarm read", ret); | ||
319 | return -EIO; | ||
320 | } | ||
321 | |||
322 | dev_dbg(dev, "%s: %02x %02x %02x %02x, %02x %02x %02x, %02x %02x\n", | ||
323 | "alarm read", | ||
324 | ds1307->regs[0], ds1307->regs[1], | ||
325 | ds1307->regs[2], ds1307->regs[3], | ||
326 | ds1307->regs[4], ds1307->regs[5], | ||
327 | ds1307->regs[6], ds1307->regs[7], | ||
328 | ds1307->regs[8]); | ||
329 | |||
330 | /* report alarm time (ALARM1); assume 24 hour and day-of-month modes, | ||
331 | * and that all four fields are checked matches | ||
332 | */ | ||
333 | t->time.tm_sec = bcd2bin(ds1307->regs[0] & 0x7f); | ||
334 | t->time.tm_min = bcd2bin(ds1307->regs[1] & 0x7f); | ||
335 | t->time.tm_hour = bcd2bin(ds1307->regs[2] & 0x3f); | ||
336 | t->time.tm_mday = bcd2bin(ds1307->regs[3] & 0x3f); | ||
337 | t->time.tm_mon = -1; | ||
338 | t->time.tm_year = -1; | ||
339 | t->time.tm_wday = -1; | ||
340 | t->time.tm_yday = -1; | ||
341 | t->time.tm_isdst = -1; | ||
342 | |||
343 | /* ... and status */ | ||
344 | t->enabled = !!(ds1307->regs[7] & DS1337_BIT_A1IE); | ||
345 | t->pending = !!(ds1307->regs[8] & DS1337_BIT_A1I); | ||
346 | |||
347 | dev_dbg(dev, "%s secs=%d, mins=%d, " | ||
348 | "hours=%d, mday=%d, enabled=%d, pending=%d\n", | ||
349 | "alarm read", t->time.tm_sec, t->time.tm_min, | ||
350 | t->time.tm_hour, t->time.tm_mday, | ||
351 | t->enabled, t->pending); | ||
352 | |||
353 | return 0; | ||
354 | } | ||
355 | |||
356 | static int ds1307_set_alarm(struct device *dev, struct rtc_wkalrm *t) | ||
357 | { | ||
358 | struct i2c_client *client = to_i2c_client(dev); | ||
359 | struct ds1307 *ds1307 = i2c_get_clientdata(client); | ||
360 | unsigned char *buf = ds1307->regs; | ||
361 | u8 control, status; | ||
362 | int ret; | ||
363 | |||
364 | if (!test_bit(HAS_ALARM, &ds1307->flags)) | ||
365 | return -EINVAL; | ||
366 | |||
367 | dev_dbg(dev, "%s secs=%d, mins=%d, " | ||
368 | "hours=%d, mday=%d, enabled=%d, pending=%d\n", | ||
369 | "alarm set", t->time.tm_sec, t->time.tm_min, | ||
370 | t->time.tm_hour, t->time.tm_mday, | ||
371 | t->enabled, t->pending); | ||
372 | |||
373 | /* read current status of both alarms and the chip */ | ||
374 | ds1307->reg_addr = DS1339_REG_ALARM1_SECS; | ||
375 | ds1307->msg[1].flags = I2C_M_RD; | ||
376 | ds1307->msg[1].len = 9; | ||
377 | |||
378 | ret = i2c_transfer(to_i2c_adapter(client->dev.parent), | ||
379 | ds1307->msg, 2); | ||
380 | if (ret != 2) { | ||
381 | dev_err(dev, "%s error %d\n", "alarm write", ret); | ||
382 | return -EIO; | ||
383 | } | ||
384 | control = ds1307->regs[7]; | ||
385 | status = ds1307->regs[8]; | ||
386 | |||
387 | dev_dbg(dev, "%s: %02x %02x %02x %02x, %02x %02x %02x, %02x %02x\n", | ||
388 | "alarm set (old status)", | ||
389 | ds1307->regs[0], ds1307->regs[1], | ||
390 | ds1307->regs[2], ds1307->regs[3], | ||
391 | ds1307->regs[4], ds1307->regs[5], | ||
392 | ds1307->regs[6], control, status); | ||
393 | |||
394 | /* set ALARM1, using 24 hour and day-of-month modes */ | ||
395 | *buf++ = DS1339_REG_ALARM1_SECS; /* first register addr */ | ||
396 | buf[0] = bin2bcd(t->time.tm_sec); | ||
397 | buf[1] = bin2bcd(t->time.tm_min); | ||
398 | buf[2] = bin2bcd(t->time.tm_hour); | ||
399 | buf[3] = bin2bcd(t->time.tm_mday); | ||
400 | |||
401 | /* set ALARM2 to non-garbage */ | ||
402 | buf[4] = 0; | ||
403 | buf[5] = 0; | ||
404 | buf[6] = 0; | ||
405 | |||
406 | /* optionally enable ALARM1 */ | ||
407 | buf[7] = control & ~(DS1337_BIT_A1IE | DS1337_BIT_A2IE); | ||
408 | if (t->enabled) { | ||
409 | dev_dbg(dev, "alarm IRQ armed\n"); | ||
410 | buf[7] |= DS1337_BIT_A1IE; /* only ALARM1 is used */ | ||
411 | } | ||
412 | buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I); | ||
413 | |||
414 | ds1307->msg[1].flags = 0; | ||
415 | ds1307->msg[1].len = 10; | ||
416 | |||
417 | ret = i2c_transfer(to_i2c_adapter(client->dev.parent), | ||
418 | &ds1307->msg[1], 1); | ||
419 | if (ret != 1) { | ||
420 | dev_err(dev, "can't set alarm time\n"); | ||
421 | return -EIO; | ||
422 | } | ||
423 | |||
424 | return 0; | ||
425 | } | ||
426 | |||
427 | static int ds1307_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | ||
428 | { | ||
429 | struct i2c_client *client = to_i2c_client(dev); | ||
430 | struct ds1307 *ds1307 = i2c_get_clientdata(client); | ||
431 | int ret; | ||
432 | |||
433 | switch (cmd) { | ||
434 | case RTC_AIE_OFF: | ||
435 | if (!test_bit(HAS_ALARM, &ds1307->flags)) | ||
436 | return -ENOTTY; | ||
437 | |||
438 | ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL); | ||
439 | if (ret < 0) | ||
440 | return ret; | ||
441 | |||
442 | ret &= ~DS1337_BIT_A1IE; | ||
443 | |||
444 | ret = i2c_smbus_write_byte_data(client, | ||
445 | DS1337_REG_CONTROL, ret); | ||
446 | if (ret < 0) | ||
447 | return ret; | ||
448 | |||
449 | break; | ||
450 | |||
451 | case RTC_AIE_ON: | ||
452 | if (!test_bit(HAS_ALARM, &ds1307->flags)) | ||
453 | return -ENOTTY; | ||
454 | |||
455 | ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL); | ||
456 | if (ret < 0) | ||
457 | return ret; | ||
458 | |||
459 | ret |= DS1337_BIT_A1IE; | ||
460 | |||
461 | ret = i2c_smbus_write_byte_data(client, | ||
462 | DS1337_REG_CONTROL, ret); | ||
463 | if (ret < 0) | ||
464 | return ret; | ||
465 | |||
466 | break; | ||
467 | |||
468 | default: | ||
469 | return -ENOIOCTLCMD; | ||
470 | } | ||
471 | |||
472 | return 0; | ||
473 | } | ||
474 | |||
234 | static const struct rtc_class_ops ds13xx_rtc_ops = { | 475 | static const struct rtc_class_ops ds13xx_rtc_ops = { |
235 | .read_time = ds1307_get_time, | 476 | .read_time = ds1307_get_time, |
236 | .set_time = ds1307_set_time, | 477 | .set_time = ds1307_set_time, |
478 | .read_alarm = ds1307_read_alarm, | ||
479 | .set_alarm = ds1307_set_alarm, | ||
480 | .ioctl = ds1307_ioctl, | ||
237 | }; | 481 | }; |
238 | 482 | ||
239 | /*----------------------------------------------------------------------*/ | 483 | /*----------------------------------------------------------------------*/ |
@@ -327,6 +571,7 @@ static int __devinit ds1307_probe(struct i2c_client *client, | |||
327 | int tmp; | 571 | int tmp; |
328 | const struct chip_desc *chip = &chips[id->driver_data]; | 572 | const struct chip_desc *chip = &chips[id->driver_data]; |
329 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 573 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
574 | int want_irq = false; | ||
330 | 575 | ||
331 | if (!i2c_check_functionality(adapter, | 576 | if (!i2c_check_functionality(adapter, |
332 | I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) | 577 | I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) |
@@ -353,6 +598,12 @@ static int __devinit ds1307_probe(struct i2c_client *client, | |||
353 | switch (ds1307->type) { | 598 | switch (ds1307->type) { |
354 | case ds_1337: | 599 | case ds_1337: |
355 | case ds_1339: | 600 | case ds_1339: |
601 | /* has IRQ? */ | ||
602 | if (ds1307->client->irq > 0 && chip->alarm) { | ||
603 | INIT_WORK(&ds1307->work, ds1307_work); | ||
604 | want_irq = true; | ||
605 | } | ||
606 | |||
356 | ds1307->reg_addr = DS1337_REG_CONTROL; | 607 | ds1307->reg_addr = DS1337_REG_CONTROL; |
357 | ds1307->msg[1].len = 2; | 608 | ds1307->msg[1].len = 2; |
358 | 609 | ||
@@ -369,8 +620,20 @@ static int __devinit ds1307_probe(struct i2c_client *client, | |||
369 | 620 | ||
370 | /* oscillator off? turn it on, so clock can tick. */ | 621 | /* oscillator off? turn it on, so clock can tick. */ |
371 | if (ds1307->regs[0] & DS1337_BIT_nEOSC) | 622 | if (ds1307->regs[0] & DS1337_BIT_nEOSC) |
372 | i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, | 623 | ds1307->regs[0] &= ~DS1337_BIT_nEOSC; |
373 | ds1307->regs[0] & ~DS1337_BIT_nEOSC); | 624 | |
625 | /* Using IRQ? Disable the square wave and both alarms. | ||
626 | * For ds1339, be sure alarms can trigger when we're | ||
627 | * running on Vbackup (BBSQI); we assume ds1337 will | ||
628 | * ignore that bit | ||
629 | */ | ||
630 | if (want_irq) { | ||
631 | ds1307->regs[0] |= DS1337_BIT_INTCN | DS1339_BIT_BBSQI; | ||
632 | ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE); | ||
633 | } | ||
634 | |||
635 | i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, | ||
636 | ds1307->regs[0]); | ||
374 | 637 | ||
375 | /* oscillator fault? clear flag, and warn */ | 638 | /* oscillator fault? clear flag, and warn */ |
376 | if (ds1307->regs[1] & DS1337_BIT_OSF) { | 639 | if (ds1307->regs[1] & DS1337_BIT_OSF) { |
@@ -495,10 +758,22 @@ read_rtc: | |||
495 | goto exit_free; | 758 | goto exit_free; |
496 | } | 759 | } |
497 | 760 | ||
761 | if (want_irq) { | ||
762 | err = request_irq(client->irq, ds1307_irq, 0, | ||
763 | ds1307->rtc->name, client); | ||
764 | if (err) { | ||
765 | dev_err(&client->dev, | ||
766 | "unable to request IRQ!\n"); | ||
767 | goto exit_irq; | ||
768 | } | ||
769 | set_bit(HAS_ALARM, &ds1307->flags); | ||
770 | dev_dbg(&client->dev, "got IRQ %d\n", client->irq); | ||
771 | } | ||
772 | |||
498 | if (chip->nvram56) { | 773 | if (chip->nvram56) { |
499 | err = sysfs_create_bin_file(&client->dev.kobj, &nvram); | 774 | err = sysfs_create_bin_file(&client->dev.kobj, &nvram); |
500 | if (err == 0) { | 775 | if (err == 0) { |
501 | ds1307->has_nvram = true; | 776 | set_bit(HAS_NVRAM, &ds1307->flags); |
502 | dev_info(&client->dev, "56 bytes nvram\n"); | 777 | dev_info(&client->dev, "56 bytes nvram\n"); |
503 | } | 778 | } |
504 | } | 779 | } |
@@ -512,7 +787,9 @@ exit_bad: | |||
512 | ds1307->regs[2], ds1307->regs[3], | 787 | ds1307->regs[2], ds1307->regs[3], |
513 | ds1307->regs[4], ds1307->regs[5], | 788 | ds1307->regs[4], ds1307->regs[5], |
514 | ds1307->regs[6]); | 789 | ds1307->regs[6]); |
515 | 790 | exit_irq: | |
791 | if (ds1307->rtc) | ||
792 | rtc_device_unregister(ds1307->rtc); | ||
516 | exit_free: | 793 | exit_free: |
517 | kfree(ds1307); | 794 | kfree(ds1307); |
518 | return err; | 795 | return err; |
@@ -520,9 +797,14 @@ exit_free: | |||
520 | 797 | ||
521 | static int __devexit ds1307_remove(struct i2c_client *client) | 798 | static int __devexit ds1307_remove(struct i2c_client *client) |
522 | { | 799 | { |
523 | struct ds1307 *ds1307 = i2c_get_clientdata(client); | 800 | struct ds1307 *ds1307 = i2c_get_clientdata(client); |
801 | |||
802 | if (test_and_clear_bit(HAS_ALARM, &ds1307->flags)) { | ||
803 | free_irq(client->irq, client); | ||
804 | cancel_work_sync(&ds1307->work); | ||
805 | } | ||
524 | 806 | ||
525 | if (ds1307->has_nvram) | 807 | if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags)) |
526 | sysfs_remove_bin_file(&client->dev.kobj, &nvram); | 808 | sysfs_remove_bin_file(&client->dev.kobj, &nvram); |
527 | 809 | ||
528 | rtc_device_unregister(ds1307->rtc); | 810 | rtc_device_unregister(ds1307->rtc); |