diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/rtc/rtc-cmos.c | 70 |
1 files changed, 63 insertions, 7 deletions
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 963ad0b6a4e9..f1695d7fa0fa 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -143,6 +143,43 @@ static inline int hpet_unregister_irq_handler(irq_handler_t handler) | |||
143 | 143 | ||
144 | /*----------------------------------------------------------------*/ | 144 | /*----------------------------------------------------------------*/ |
145 | 145 | ||
146 | #ifdef RTC_PORT | ||
147 | |||
148 | /* Most newer x86 systems have two register banks, the first used | ||
149 | * for RTC and NVRAM and the second only for NVRAM. Caller must | ||
150 | * own rtc_lock ... and we won't worry about access during NMI. | ||
151 | */ | ||
152 | #define can_bank2 true | ||
153 | |||
154 | static inline unsigned char cmos_read_bank2(unsigned char addr) | ||
155 | { | ||
156 | outb(addr, RTC_PORT(2)); | ||
157 | return inb(RTC_PORT(3)); | ||
158 | } | ||
159 | |||
160 | static inline void cmos_write_bank2(unsigned char val, unsigned char addr) | ||
161 | { | ||
162 | outb(addr, RTC_PORT(2)); | ||
163 | outb(val, RTC_PORT(2)); | ||
164 | } | ||
165 | |||
166 | #else | ||
167 | |||
168 | #define can_bank2 false | ||
169 | |||
170 | static inline unsigned char cmos_read_bank2(unsigned char addr) | ||
171 | { | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static inline void cmos_write_bank2(unsigned char val, unsigned char addr) | ||
176 | { | ||
177 | } | ||
178 | |||
179 | #endif | ||
180 | |||
181 | /*----------------------------------------------------------------*/ | ||
182 | |||
146 | static int cmos_read_time(struct device *dev, struct rtc_time *t) | 183 | static int cmos_read_time(struct device *dev, struct rtc_time *t) |
147 | { | 184 | { |
148 | /* REVISIT: if the clock has a "century" register, use | 185 | /* REVISIT: if the clock has a "century" register, use |
@@ -491,12 +528,21 @@ cmos_nvram_read(struct kobject *kobj, struct bin_attribute *attr, | |||
491 | 528 | ||
492 | if (unlikely(off >= attr->size)) | 529 | if (unlikely(off >= attr->size)) |
493 | return 0; | 530 | return 0; |
531 | if (unlikely(off < 0)) | ||
532 | return -EINVAL; | ||
494 | if ((off + count) > attr->size) | 533 | if ((off + count) > attr->size) |
495 | count = attr->size - off; | 534 | count = attr->size - off; |
496 | 535 | ||
536 | off += NVRAM_OFFSET; | ||
497 | spin_lock_irq(&rtc_lock); | 537 | spin_lock_irq(&rtc_lock); |
498 | for (retval = 0, off += NVRAM_OFFSET; count--; retval++, off++) | 538 | for (retval = 0; count; count--, off++, retval++) { |
499 | *buf++ = CMOS_READ(off); | 539 | if (off < 128) |
540 | *buf++ = CMOS_READ(off); | ||
541 | else if (can_bank2) | ||
542 | *buf++ = cmos_read_bank2(off); | ||
543 | else | ||
544 | break; | ||
545 | } | ||
500 | spin_unlock_irq(&rtc_lock); | 546 | spin_unlock_irq(&rtc_lock); |
501 | 547 | ||
502 | return retval; | 548 | return retval; |
@@ -512,6 +558,8 @@ cmos_nvram_write(struct kobject *kobj, struct bin_attribute *attr, | |||
512 | cmos = dev_get_drvdata(container_of(kobj, struct device, kobj)); | 558 | cmos = dev_get_drvdata(container_of(kobj, struct device, kobj)); |
513 | if (unlikely(off >= attr->size)) | 559 | if (unlikely(off >= attr->size)) |
514 | return -EFBIG; | 560 | return -EFBIG; |
561 | if (unlikely(off < 0)) | ||
562 | return -EINVAL; | ||
515 | if ((off + count) > attr->size) | 563 | if ((off + count) > attr->size) |
516 | count = attr->size - off; | 564 | count = attr->size - off; |
517 | 565 | ||
@@ -520,15 +568,20 @@ cmos_nvram_write(struct kobject *kobj, struct bin_attribute *attr, | |||
520 | * here. If userspace is smart enough to know what fields of | 568 | * here. If userspace is smart enough to know what fields of |
521 | * NVRAM to update, updating checksums is also part of its job. | 569 | * NVRAM to update, updating checksums is also part of its job. |
522 | */ | 570 | */ |
571 | off += NVRAM_OFFSET; | ||
523 | spin_lock_irq(&rtc_lock); | 572 | spin_lock_irq(&rtc_lock); |
524 | for (retval = 0, off += NVRAM_OFFSET; count--; retval++, off++) { | 573 | for (retval = 0; count; count--, off++, retval++) { |
525 | /* don't trash RTC registers */ | 574 | /* don't trash RTC registers */ |
526 | if (off == cmos->day_alrm | 575 | if (off == cmos->day_alrm |
527 | || off == cmos->mon_alrm | 576 | || off == cmos->mon_alrm |
528 | || off == cmos->century) | 577 | || off == cmos->century) |
529 | buf++; | 578 | buf++; |
530 | else | 579 | else if (off < 128) |
531 | CMOS_WRITE(*buf++, off); | 580 | CMOS_WRITE(*buf++, off); |
581 | else if (can_bank2) | ||
582 | cmos_write_bank2(*buf++, off); | ||
583 | else | ||
584 | break; | ||
532 | } | 585 | } |
533 | spin_unlock_irq(&rtc_lock); | 586 | spin_unlock_irq(&rtc_lock); |
534 | 587 | ||
@@ -631,8 +684,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
631 | 684 | ||
632 | /* Heuristic to deduce NVRAM size ... do what the legacy NVRAM | 685 | /* Heuristic to deduce NVRAM size ... do what the legacy NVRAM |
633 | * driver did, but don't reject unknown configs. Old hardware | 686 | * driver did, but don't reject unknown configs. Old hardware |
634 | * won't address 128 bytes, and for now we ignore the way newer | 687 | * won't address 128 bytes. Newer chips have multiple banks, |
635 | * chips can address 256 bytes (using two more i/o ports). | 688 | * though they may not be listed in one I/O resource. |
636 | */ | 689 | */ |
637 | #if defined(CONFIG_ATARI) | 690 | #if defined(CONFIG_ATARI) |
638 | address_space = 64; | 691 | address_space = 64; |
@@ -642,6 +695,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
642 | #warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes. | 695 | #warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes. |
643 | address_space = 128; | 696 | address_space = 128; |
644 | #endif | 697 | #endif |
698 | if (can_bank2 && ports->end > (ports->start + 1)) | ||
699 | address_space = 256; | ||
645 | 700 | ||
646 | /* For ACPI systems extension info comes from the FADT. On others, | 701 | /* For ACPI systems extension info comes from the FADT. On others, |
647 | * board specific setup provides it as appropriate. Systems where | 702 | * board specific setup provides it as appropriate. Systems where |
@@ -740,7 +795,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
740 | goto cleanup2; | 795 | goto cleanup2; |
741 | } | 796 | } |
742 | 797 | ||
743 | pr_info("%s: alarms up to one %s%s%s\n", | 798 | pr_info("%s: alarms up to one %s%s, %zd bytes nvram, %s irqs\n", |
744 | cmos_rtc.rtc->dev.bus_id, | 799 | cmos_rtc.rtc->dev.bus_id, |
745 | is_valid_irq(rtc_irq) | 800 | is_valid_irq(rtc_irq) |
746 | ? (cmos_rtc.mon_alrm | 801 | ? (cmos_rtc.mon_alrm |
@@ -749,6 +804,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
749 | ? "month" : "day")) | 804 | ? "month" : "day")) |
750 | : "no", | 805 | : "no", |
751 | cmos_rtc.century ? ", y3k" : "", | 806 | cmos_rtc.century ? ", y3k" : "", |
807 | nvram.size, | ||
752 | is_hpet_enabled() ? ", hpet irqs" : ""); | 808 | is_hpet_enabled() ? ", hpet irqs" : ""); |
753 | 809 | ||
754 | return 0; | 810 | return 0; |