diff options
Diffstat (limited to 'drivers/rtc/rtc-ds1511.c')
-rw-r--r-- | drivers/rtc/rtc-ds1511.c | 93 |
1 files changed, 44 insertions, 49 deletions
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index 6ce8a997cf51..308a8fefe76f 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c | |||
@@ -104,31 +104,31 @@ static DEFINE_SPINLOCK(ds1511_lock); | |||
104 | static __iomem char *ds1511_base; | 104 | static __iomem char *ds1511_base; |
105 | static u32 reg_spacing = 1; | 105 | static u32 reg_spacing = 1; |
106 | 106 | ||
107 | static noinline void | 107 | static noinline void |
108 | rtc_write(uint8_t val, uint32_t reg) | 108 | rtc_write(uint8_t val, uint32_t reg) |
109 | { | 109 | { |
110 | writeb(val, ds1511_base + (reg * reg_spacing)); | 110 | writeb(val, ds1511_base + (reg * reg_spacing)); |
111 | } | 111 | } |
112 | 112 | ||
113 | static inline void | 113 | static inline void |
114 | rtc_write_alarm(uint8_t val, enum ds1511reg reg) | 114 | rtc_write_alarm(uint8_t val, enum ds1511reg reg) |
115 | { | 115 | { |
116 | rtc_write((val | 0x80), reg); | 116 | rtc_write((val | 0x80), reg); |
117 | } | 117 | } |
118 | 118 | ||
119 | static noinline uint8_t | 119 | static noinline uint8_t |
120 | rtc_read(enum ds1511reg reg) | 120 | rtc_read(enum ds1511reg reg) |
121 | { | 121 | { |
122 | return readb(ds1511_base + (reg * reg_spacing)); | 122 | return readb(ds1511_base + (reg * reg_spacing)); |
123 | } | 123 | } |
124 | 124 | ||
125 | static inline void | 125 | static inline void |
126 | rtc_disable_update(void) | 126 | rtc_disable_update(void) |
127 | { | 127 | { |
128 | rtc_write((rtc_read(RTC_CMD) & ~RTC_TE), RTC_CMD); | 128 | rtc_write((rtc_read(RTC_CMD) & ~RTC_TE), RTC_CMD); |
129 | } | 129 | } |
130 | 130 | ||
131 | static void | 131 | static void |
132 | rtc_enable_update(void) | 132 | rtc_enable_update(void) |
133 | { | 133 | { |
134 | rtc_write((rtc_read(RTC_CMD) | RTC_TE), RTC_CMD); | 134 | rtc_write((rtc_read(RTC_CMD) | RTC_TE), RTC_CMD); |
@@ -145,7 +145,7 @@ rtc_enable_update(void) | |||
145 | * just enough code to set the watchdog timer so that it | 145 | * just enough code to set the watchdog timer so that it |
146 | * will reboot the system | 146 | * will reboot the system |
147 | */ | 147 | */ |
148 | void | 148 | void |
149 | ds1511_wdog_set(unsigned long deciseconds) | 149 | ds1511_wdog_set(unsigned long deciseconds) |
150 | { | 150 | { |
151 | /* | 151 | /* |
@@ -163,7 +163,7 @@ ds1511_wdog_set(unsigned long deciseconds) | |||
163 | rtc_write(DS1511_WDE | DS1511_WDS, RTC_CMD); | 163 | rtc_write(DS1511_WDE | DS1511_WDS, RTC_CMD); |
164 | } | 164 | } |
165 | 165 | ||
166 | void | 166 | void |
167 | ds1511_wdog_disable(void) | 167 | ds1511_wdog_disable(void) |
168 | { | 168 | { |
169 | /* | 169 | /* |
@@ -191,13 +191,12 @@ static int ds1511_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm) | |||
191 | /* | 191 | /* |
192 | * won't have to change this for a while | 192 | * won't have to change this for a while |
193 | */ | 193 | */ |
194 | if (rtc_tm->tm_year < 1900) { | 194 | if (rtc_tm->tm_year < 1900) |
195 | rtc_tm->tm_year += 1900; | 195 | rtc_tm->tm_year += 1900; |
196 | } | ||
197 | 196 | ||
198 | if (rtc_tm->tm_year < 1970) { | 197 | if (rtc_tm->tm_year < 1970) |
199 | return -EINVAL; | 198 | return -EINVAL; |
200 | } | 199 | |
201 | yrs = rtc_tm->tm_year % 100; | 200 | yrs = rtc_tm->tm_year % 100; |
202 | cen = rtc_tm->tm_year / 100; | 201 | cen = rtc_tm->tm_year / 100; |
203 | mon = rtc_tm->tm_mon + 1; /* tm_mon starts at zero */ | 202 | mon = rtc_tm->tm_mon + 1; /* tm_mon starts at zero */ |
@@ -207,17 +206,14 @@ static int ds1511_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm) | |||
207 | min = rtc_tm->tm_min; | 206 | min = rtc_tm->tm_min; |
208 | sec = rtc_tm->tm_sec; | 207 | sec = rtc_tm->tm_sec; |
209 | 208 | ||
210 | if ((mon > 12) || (day == 0)) { | 209 | if ((mon > 12) || (day == 0)) |
211 | return -EINVAL; | 210 | return -EINVAL; |
212 | } | ||
213 | 211 | ||
214 | if (day > rtc_month_days(rtc_tm->tm_mon, rtc_tm->tm_year)) { | 212 | if (day > rtc_month_days(rtc_tm->tm_mon, rtc_tm->tm_year)) |
215 | return -EINVAL; | 213 | return -EINVAL; |
216 | } | ||
217 | 214 | ||
218 | if ((hrs >= 24) || (min >= 60) || (sec >= 60)) { | 215 | if ((hrs >= 24) || (min >= 60) || (sec >= 60)) |
219 | return -EINVAL; | 216 | return -EINVAL; |
220 | } | ||
221 | 217 | ||
222 | /* | 218 | /* |
223 | * each register is a different number of valid bits | 219 | * each register is a different number of valid bits |
@@ -299,7 +295,7 @@ static int ds1511_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm) | |||
299 | * date/hours/mins/secs matches. the ds1511 has many more | 295 | * date/hours/mins/secs matches. the ds1511 has many more |
300 | * permutations, but the kernel doesn't. | 296 | * permutations, but the kernel doesn't. |
301 | */ | 297 | */ |
302 | static void | 298 | static void |
303 | ds1511_rtc_update_alarm(struct rtc_plat_data *pdata) | 299 | ds1511_rtc_update_alarm(struct rtc_plat_data *pdata) |
304 | { | 300 | { |
305 | unsigned long flags; | 301 | unsigned long flags; |
@@ -322,7 +318,7 @@ ds1511_rtc_update_alarm(struct rtc_plat_data *pdata) | |||
322 | spin_unlock_irqrestore(&pdata->lock, flags); | 318 | spin_unlock_irqrestore(&pdata->lock, flags); |
323 | } | 319 | } |
324 | 320 | ||
325 | static int | 321 | static int |
326 | ds1511_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | 322 | ds1511_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
327 | { | 323 | { |
328 | struct platform_device *pdev = to_platform_device(dev); | 324 | struct platform_device *pdev = to_platform_device(dev); |
@@ -335,14 +331,14 @@ ds1511_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
335 | pdata->alrm_hour = alrm->time.tm_hour; | 331 | pdata->alrm_hour = alrm->time.tm_hour; |
336 | pdata->alrm_min = alrm->time.tm_min; | 332 | pdata->alrm_min = alrm->time.tm_min; |
337 | pdata->alrm_sec = alrm->time.tm_sec; | 333 | pdata->alrm_sec = alrm->time.tm_sec; |
338 | if (alrm->enabled) { | 334 | if (alrm->enabled) |
339 | pdata->irqen |= RTC_AF; | 335 | pdata->irqen |= RTC_AF; |
340 | } | 336 | |
341 | ds1511_rtc_update_alarm(pdata); | 337 | ds1511_rtc_update_alarm(pdata); |
342 | return 0; | 338 | return 0; |
343 | } | 339 | } |
344 | 340 | ||
345 | static int | 341 | static int |
346 | ds1511_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | 342 | ds1511_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
347 | { | 343 | { |
348 | struct platform_device *pdev = to_platform_device(dev); | 344 | struct platform_device *pdev = to_platform_device(dev); |
@@ -359,7 +355,7 @@ ds1511_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
359 | return 0; | 355 | return 0; |
360 | } | 356 | } |
361 | 357 | ||
362 | static irqreturn_t | 358 | static irqreturn_t |
363 | ds1511_interrupt(int irq, void *dev_id) | 359 | ds1511_interrupt(int irq, void *dev_id) |
364 | { | 360 | { |
365 | struct platform_device *pdev = dev_id; | 361 | struct platform_device *pdev = dev_id; |
@@ -406,7 +402,7 @@ static const struct rtc_class_ops ds1511_rtc_ops = { | |||
406 | .alarm_irq_enable = ds1511_rtc_alarm_irq_enable, | 402 | .alarm_irq_enable = ds1511_rtc_alarm_irq_enable, |
407 | }; | 403 | }; |
408 | 404 | ||
409 | static ssize_t | 405 | static ssize_t |
410 | ds1511_nvram_read(struct file *filp, struct kobject *kobj, | 406 | ds1511_nvram_read(struct file *filp, struct kobject *kobj, |
411 | struct bin_attribute *ba, | 407 | struct bin_attribute *ba, |
412 | char *buf, loff_t pos, size_t size) | 408 | char *buf, loff_t pos, size_t size) |
@@ -417,26 +413,26 @@ ds1511_nvram_read(struct file *filp, struct kobject *kobj, | |||
417 | * if count is more than one, turn on "burst" mode | 413 | * if count is more than one, turn on "burst" mode |
418 | * turn it off when you're done | 414 | * turn it off when you're done |
419 | */ | 415 | */ |
420 | if (size > 1) { | 416 | if (size > 1) |
421 | rtc_write((rtc_read(RTC_CMD) | DS1511_BME), RTC_CMD); | 417 | rtc_write((rtc_read(RTC_CMD) | DS1511_BME), RTC_CMD); |
422 | } | 418 | |
423 | if (pos > DS1511_RAM_MAX) { | 419 | if (pos > DS1511_RAM_MAX) |
424 | pos = DS1511_RAM_MAX; | 420 | pos = DS1511_RAM_MAX; |
425 | } | 421 | |
426 | if (size + pos > DS1511_RAM_MAX + 1) { | 422 | if (size + pos > DS1511_RAM_MAX + 1) |
427 | size = DS1511_RAM_MAX - pos + 1; | 423 | size = DS1511_RAM_MAX - pos + 1; |
428 | } | 424 | |
429 | rtc_write(pos, DS1511_RAMADDR_LSB); | 425 | rtc_write(pos, DS1511_RAMADDR_LSB); |
430 | for (count = 0; size > 0; count++, size--) { | 426 | for (count = 0; size > 0; count++, size--) |
431 | *buf++ = rtc_read(DS1511_RAMDATA); | 427 | *buf++ = rtc_read(DS1511_RAMDATA); |
432 | } | 428 | |
433 | if (count > 1) { | 429 | if (count > 1) |
434 | rtc_write((rtc_read(RTC_CMD) & ~DS1511_BME), RTC_CMD); | 430 | rtc_write((rtc_read(RTC_CMD) & ~DS1511_BME), RTC_CMD); |
435 | } | 431 | |
436 | return count; | 432 | return count; |
437 | } | 433 | } |
438 | 434 | ||
439 | static ssize_t | 435 | static ssize_t |
440 | ds1511_nvram_write(struct file *filp, struct kobject *kobj, | 436 | ds1511_nvram_write(struct file *filp, struct kobject *kobj, |
441 | struct bin_attribute *bin_attr, | 437 | struct bin_attribute *bin_attr, |
442 | char *buf, loff_t pos, size_t size) | 438 | char *buf, loff_t pos, size_t size) |
@@ -447,22 +443,22 @@ ds1511_nvram_write(struct file *filp, struct kobject *kobj, | |||
447 | * if count is more than one, turn on "burst" mode | 443 | * if count is more than one, turn on "burst" mode |
448 | * turn it off when you're done | 444 | * turn it off when you're done |
449 | */ | 445 | */ |
450 | if (size > 1) { | 446 | if (size > 1) |
451 | rtc_write((rtc_read(RTC_CMD) | DS1511_BME), RTC_CMD); | 447 | rtc_write((rtc_read(RTC_CMD) | DS1511_BME), RTC_CMD); |
452 | } | 448 | |
453 | if (pos > DS1511_RAM_MAX) { | 449 | if (pos > DS1511_RAM_MAX) |
454 | pos = DS1511_RAM_MAX; | 450 | pos = DS1511_RAM_MAX; |
455 | } | 451 | |
456 | if (size + pos > DS1511_RAM_MAX + 1) { | 452 | if (size + pos > DS1511_RAM_MAX + 1) |
457 | size = DS1511_RAM_MAX - pos + 1; | 453 | size = DS1511_RAM_MAX - pos + 1; |
458 | } | 454 | |
459 | rtc_write(pos, DS1511_RAMADDR_LSB); | 455 | rtc_write(pos, DS1511_RAMADDR_LSB); |
460 | for (count = 0; size > 0; count++, size--) { | 456 | for (count = 0; size > 0; count++, size--) |
461 | rtc_write(*buf++, DS1511_RAMDATA); | 457 | rtc_write(*buf++, DS1511_RAMDATA); |
462 | } | 458 | |
463 | if (count > 1) { | 459 | if (count > 1) |
464 | rtc_write((rtc_read(RTC_CMD) & ~DS1511_BME), RTC_CMD); | 460 | rtc_write((rtc_read(RTC_CMD) & ~DS1511_BME), RTC_CMD); |
465 | } | 461 | |
466 | return count; | 462 | return count; |
467 | } | 463 | } |
468 | 464 | ||
@@ -484,9 +480,9 @@ static int ds1511_rtc_probe(struct platform_device *pdev) | |||
484 | int ret = 0; | 480 | int ret = 0; |
485 | 481 | ||
486 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 482 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
487 | if (!res) { | 483 | if (!res) |
488 | return -ENODEV; | 484 | return -ENODEV; |
489 | } | 485 | |
490 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | 486 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); |
491 | if (!pdata) | 487 | if (!pdata) |
492 | return -ENOMEM; | 488 | return -ENOMEM; |
@@ -518,9 +514,8 @@ static int ds1511_rtc_probe(struct platform_device *pdev) | |||
518 | /* | 514 | /* |
519 | * check for a dying bat-tree | 515 | * check for a dying bat-tree |
520 | */ | 516 | */ |
521 | if (rtc_read(RTC_CMD1) & DS1511_BLF1) { | 517 | if (rtc_read(RTC_CMD1) & DS1511_BLF1) |
522 | dev_warn(&pdev->dev, "voltage-low detected.\n"); | 518 | dev_warn(&pdev->dev, "voltage-low detected.\n"); |
523 | } | ||
524 | 519 | ||
525 | spin_lock_init(&pdata->lock); | 520 | spin_lock_init(&pdata->lock); |
526 | platform_set_drvdata(pdev, pdata); | 521 | platform_set_drvdata(pdev, pdata); |