aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-08-29 00:06:27 -0400
committerDavid S. Miller <davem@davemloft.net>2008-08-29 17:16:47 -0400
commit1518e7ed08019539498f772faa1f9368fed91361 (patch)
tree386393bea6adeba85bb81ae8add9930945f793d7 /arch/sparc64
parenta0b31b578f9ab34826703762113f9d42f3ae9819 (diff)
sparc64: Convert Mostek rtc to use generic RTC layer driver.
Based largely upon a patch by Krzysztof Helt <krzysztof.h1@poczta.fm> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64')
-rw-r--r--arch/sparc64/Kconfig1
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c3
-rw-r--r--arch/sparc64/kernel/time.c416
3 files changed, 103 insertions, 317 deletions
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index 19f0cc8a21ed..0a4e342c041d 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -20,6 +20,7 @@ config SPARC64
20 select HAVE_ARCH_TRACEHOOK 20 select HAVE_ARCH_TRACEHOOK
21 select ARCH_WANT_OPTIONAL_GPIOLIB 21 select ARCH_WANT_OPTIONAL_GPIOLIB
22 select RTC_CLASS 22 select RTC_CLASS
23 select RTC_DRV_M48T59
23 24
24config GENERIC_TIME 25config GENERIC_TIME
25 bool 26 bool
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index 142c16983d14..4c3a6a87c8a4 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -36,7 +36,6 @@
36#include <asm/elf.h> 36#include <asm/elf.h>
37#include <asm/head.h> 37#include <asm/head.h>
38#include <asm/smp.h> 38#include <asm/smp.h>
39#include <asm/mostek.h>
40#include <asm/ptrace.h> 39#include <asm/ptrace.h>
41#include <asm/uaccess.h> 40#include <asm/uaccess.h>
42#include <asm/checksum.h> 41#include <asm/checksum.h>
@@ -152,8 +151,6 @@ EXPORT_SYMBOL(flush_dcache_page);
152EXPORT_SYMBOL(__flush_dcache_range); 151EXPORT_SYMBOL(__flush_dcache_range);
153#endif 152#endif
154 153
155EXPORT_SYMBOL(mostek_lock);
156EXPORT_SYMBOL(mstk48t02_regs);
157#ifdef CONFIG_SUN_AUXIO 154#ifdef CONFIG_SUN_AUXIO
158EXPORT_SYMBOL(auxio_set_led); 155EXPORT_SYMBOL(auxio_set_led);
159EXPORT_SYMBOL(auxio_set_lte); 156EXPORT_SYMBOL(auxio_set_lte);
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index 184321b88a68..9c2c3d84443d 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -30,13 +30,14 @@
30#include <linux/percpu.h> 30#include <linux/percpu.h>
31#include <linux/miscdevice.h> 31#include <linux/miscdevice.h>
32#include <linux/rtc.h> 32#include <linux/rtc.h>
33#include <linux/rtc/m48t59.h>
33#include <linux/kernel_stat.h> 34#include <linux/kernel_stat.h>
34#include <linux/clockchips.h> 35#include <linux/clockchips.h>
35#include <linux/clocksource.h> 36#include <linux/clocksource.h>
36#include <linux/of_device.h> 37#include <linux/of_device.h>
38#include <linux/platform_device.h>
37 39
38#include <asm/oplib.h> 40#include <asm/oplib.h>
39#include <asm/mostek.h>
40#include <asm/timer.h> 41#include <asm/timer.h>
41#include <asm/irq.h> 42#include <asm/irq.h>
42#include <asm/io.h> 43#include <asm/io.h>
@@ -50,17 +51,12 @@
50 51
51#include "entry.h" 52#include "entry.h"
52 53
53DEFINE_SPINLOCK(mostek_lock);
54DEFINE_SPINLOCK(rtc_lock); 54DEFINE_SPINLOCK(rtc_lock);
55void __iomem *mstk48t02_regs = NULL;
56#ifdef CONFIG_PCI 55#ifdef CONFIG_PCI
57unsigned long ds1287_regs = 0UL; 56unsigned long ds1287_regs = 0UL;
58static void __iomem *bq4802_regs; 57static void __iomem *bq4802_regs;
59#endif 58#endif
60 59
61static void __iomem *mstk48t08_regs;
62static void __iomem *mstk48t59_regs;
63
64static int set_rtc_mmss(unsigned long); 60static int set_rtc_mmss(unsigned long);
65 61
66#define TICK_PRIV_BIT (1UL << 63) 62#define TICK_PRIV_BIT (1UL << 63)
@@ -413,144 +409,10 @@ int update_persistent_clock(struct timespec now)
413 return set_rtc_mmss(now.tv_sec); 409 return set_rtc_mmss(now.tv_sec);
414} 410}
415 411
416/* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */
417static void __init kick_start_clock(void)
418{
419 void __iomem *regs = mstk48t02_regs;
420 u8 sec, tmp;
421 int i, count;
422
423 prom_printf("CLOCK: Clock was stopped. Kick start ");
424
425 spin_lock_irq(&mostek_lock);
426
427 /* Turn on the kick start bit to start the oscillator. */
428 tmp = mostek_read(regs + MOSTEK_CREG);
429 tmp |= MSTK_CREG_WRITE;
430 mostek_write(regs + MOSTEK_CREG, tmp);
431 tmp = mostek_read(regs + MOSTEK_SEC);
432 tmp &= ~MSTK_STOP;
433 mostek_write(regs + MOSTEK_SEC, tmp);
434 tmp = mostek_read(regs + MOSTEK_HOUR);
435 tmp |= MSTK_KICK_START;
436 mostek_write(regs + MOSTEK_HOUR, tmp);
437 tmp = mostek_read(regs + MOSTEK_CREG);
438 tmp &= ~MSTK_CREG_WRITE;
439 mostek_write(regs + MOSTEK_CREG, tmp);
440
441 spin_unlock_irq(&mostek_lock);
442
443 /* Delay to allow the clock oscillator to start. */
444 sec = MSTK_REG_SEC(regs);
445 for (i = 0; i < 3; i++) {
446 while (sec == MSTK_REG_SEC(regs))
447 for (count = 0; count < 100000; count++)
448 /* nothing */ ;
449 prom_printf(".");
450 sec = MSTK_REG_SEC(regs);
451 }
452 prom_printf("\n");
453
454 spin_lock_irq(&mostek_lock);
455
456 /* Turn off kick start and set a "valid" time and date. */
457 tmp = mostek_read(regs + MOSTEK_CREG);
458 tmp |= MSTK_CREG_WRITE;
459 mostek_write(regs + MOSTEK_CREG, tmp);
460 tmp = mostek_read(regs + MOSTEK_HOUR);
461 tmp &= ~MSTK_KICK_START;
462 mostek_write(regs + MOSTEK_HOUR, tmp);
463 MSTK_SET_REG_SEC(regs,0);
464 MSTK_SET_REG_MIN(regs,0);
465 MSTK_SET_REG_HOUR(regs,0);
466 MSTK_SET_REG_DOW(regs,5);
467 MSTK_SET_REG_DOM(regs,1);
468 MSTK_SET_REG_MONTH(regs,8);
469 MSTK_SET_REG_YEAR(regs,1996 - MSTK_YEAR_ZERO);
470 tmp = mostek_read(regs + MOSTEK_CREG);
471 tmp &= ~MSTK_CREG_WRITE;
472 mostek_write(regs + MOSTEK_CREG, tmp);
473
474 spin_unlock_irq(&mostek_lock);
475
476 /* Ensure the kick start bit is off. If it isn't, turn it off. */
477 while (mostek_read(regs + MOSTEK_HOUR) & MSTK_KICK_START) {
478 prom_printf("CLOCK: Kick start still on!\n");
479
480 spin_lock_irq(&mostek_lock);
481
482 tmp = mostek_read(regs + MOSTEK_CREG);
483 tmp |= MSTK_CREG_WRITE;
484 mostek_write(regs + MOSTEK_CREG, tmp);
485
486 tmp = mostek_read(regs + MOSTEK_HOUR);
487 tmp &= ~MSTK_KICK_START;
488 mostek_write(regs + MOSTEK_HOUR, tmp);
489
490 tmp = mostek_read(regs + MOSTEK_CREG);
491 tmp &= ~MSTK_CREG_WRITE;
492 mostek_write(regs + MOSTEK_CREG, tmp);
493
494 spin_unlock_irq(&mostek_lock);
495 }
496
497 prom_printf("CLOCK: Kick start procedure successful.\n");
498}
499
500/* Return nonzero if the clock chip battery is low. */
501static int __init has_low_battery(void)
502{
503 void __iomem *regs = mstk48t02_regs;
504 u8 data1, data2;
505
506 spin_lock_irq(&mostek_lock);
507
508 data1 = mostek_read(regs + MOSTEK_EEPROM); /* Read some data. */
509 mostek_write(regs + MOSTEK_EEPROM, ~data1); /* Write back the complement. */
510 data2 = mostek_read(regs + MOSTEK_EEPROM); /* Read back the complement. */
511 mostek_write(regs + MOSTEK_EEPROM, data1); /* Restore original value. */
512
513 spin_unlock_irq(&mostek_lock);
514
515 return (data1 == data2); /* Was the write blocked? */
516}
517
518static void __init mostek_set_system_time(void __iomem *mregs)
519{
520 unsigned int year, mon, day, hour, min, sec;
521 u8 tmp;
522
523 spin_lock_irq(&mostek_lock);
524
525 /* Traditional Mostek chip. */
526 tmp = mostek_read(mregs + MOSTEK_CREG);
527 tmp |= MSTK_CREG_READ;
528 mostek_write(mregs + MOSTEK_CREG, tmp);
529
530 sec = MSTK_REG_SEC(mregs);
531 min = MSTK_REG_MIN(mregs);
532 hour = MSTK_REG_HOUR(mregs);
533 day = MSTK_REG_DOM(mregs);
534 mon = MSTK_REG_MONTH(mregs);
535 year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) );
536
537 xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
538 xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
539 set_normalized_timespec(&wall_to_monotonic,
540 -xtime.tv_sec, -xtime.tv_nsec);
541
542 tmp = mostek_read(mregs + MOSTEK_CREG);
543 tmp &= ~MSTK_CREG_READ;
544 mostek_write(mregs + MOSTEK_CREG, tmp);
545
546 spin_unlock_irq(&mostek_lock);
547}
548
549/* Probe for the real time clock chip. */ 412/* Probe for the real time clock chip. */
550static void __init set_system_time(void) 413static void __init set_system_time(void)
551{ 414{
552 unsigned int year, mon, day, hour, min, sec; 415 unsigned int year, mon, day, hour, min, sec;
553 void __iomem *mregs = mstk48t02_regs;
554#ifdef CONFIG_PCI 416#ifdef CONFIG_PCI
555 unsigned long dregs = ds1287_regs; 417 unsigned long dregs = ds1287_regs;
556 void __iomem *bregs = bq4802_regs; 418 void __iomem *bregs = bq4802_regs;
@@ -559,16 +421,11 @@ static void __init set_system_time(void)
559 void __iomem *bregs = 0UL; 421 void __iomem *bregs = 0UL;
560#endif 422#endif
561 423
562 if (!mregs && !dregs && !bregs) { 424 if (!dregs && !bregs) {
563 prom_printf("Something wrong, clock regs not mapped yet.\n"); 425 prom_printf("Something wrong, clock regs not mapped yet.\n");
564 prom_halt(); 426 prom_halt();
565 } 427 }
566 428
567 if (mregs) {
568 mostek_set_system_time(mregs);
569 return;
570 }
571
572 if (bregs) { 429 if (bregs) {
573 unsigned char val = readb(bregs + 0x0e); 430 unsigned char val = readb(bregs + 0x0e);
574 unsigned int century; 431 unsigned int century;
@@ -689,12 +546,9 @@ retry:
689 return -EOPNOTSUPP; 546 return -EOPNOTSUPP;
690} 547}
691 548
692static int __init clock_model_matches(const char *model) 549static int __init rtc_model_matches(const char *model)
693{ 550{
694 if (strcmp(model, "mk48t02") && 551 if (strcmp(model, "m5819") &&
695 strcmp(model, "mk48t08") &&
696 strcmp(model, "mk48t59") &&
697 strcmp(model, "m5819") &&
698 strcmp(model, "m5819p") && 552 strcmp(model, "m5819p") &&
699 strcmp(model, "m5823") && 553 strcmp(model, "m5823") &&
700 strcmp(model, "ds1287") && 554 strcmp(model, "ds1287") &&
@@ -704,7 +558,7 @@ static int __init clock_model_matches(const char *model)
704 return 1; 558 return 1;
705} 559}
706 560
707static int __devinit clock_probe(struct of_device *op, const struct of_device_id *match) 561static int __devinit rtc_probe(struct of_device *op, const struct of_device_id *match)
708{ 562{
709 struct device_node *dp = op->node; 563 struct device_node *dp = op->node;
710 const char *model = of_get_property(dp, "model", NULL); 564 const char *model = of_get_property(dp, "model", NULL);
@@ -715,14 +569,7 @@ static int __devinit clock_probe(struct of_device *op, const struct of_device_id
715 if (!model) 569 if (!model)
716 model = compat; 570 model = compat;
717 571
718 if (!model || !clock_model_matches(model)) 572 if (!model || !rtc_model_matches(model))
719 return -ENODEV;
720
721 /* On an Enterprise system there can be multiple mostek clocks.
722 * We should only match the one that is on the central FHC bus.
723 */
724 if (!strcmp(dp->parent->name, "fhc") &&
725 strcmp(dp->parent->parent->name, "central") != 0)
726 return -ENODEV; 573 return -ENODEV;
727 574
728 size = (op->resource[0].end - op->resource[0].start) + 1; 575 size = (op->resource[0].end - op->resource[0].start) + 1;
@@ -738,32 +585,12 @@ static int __devinit clock_probe(struct of_device *op, const struct of_device_id
738 ds1287_regs = (unsigned long) regs; 585 ds1287_regs = (unsigned long) regs;
739 } else if (!strcmp(model, "bq4802")) { 586 } else if (!strcmp(model, "bq4802")) {
740 bq4802_regs = regs; 587 bq4802_regs = regs;
741 } else
742#endif
743 if (model[5] == '0' && model[6] == '2') {
744 mstk48t02_regs = regs;
745 } else if(model[5] == '0' && model[6] == '8') {
746 mstk48t08_regs = regs;
747 mstk48t02_regs = mstk48t08_regs + MOSTEK_48T08_48T02;
748 } else {
749 mstk48t59_regs = regs;
750 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
751 } 588 }
752 589#endif
753 printk(KERN_INFO "%s: Clock regs at %p\n", dp->full_name, regs); 590 printk(KERN_INFO "%s: Clock regs at %p\n", dp->full_name, regs);
754 591
755 local_irq_save(flags); 592 local_irq_save(flags);
756 593
757 if (mstk48t02_regs != NULL) {
758 /* Report a low battery voltage condition. */
759 if (has_low_battery())
760 prom_printf("NVRAM: Low battery voltage!\n");
761
762 /* Kick start the clock if it is completely stopped. */
763 if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP)
764 kick_start_clock();
765 }
766
767 set_system_time(); 594 set_system_time();
768 595
769 local_irq_restore(flags); 596 local_irq_restore(flags);
@@ -771,21 +598,102 @@ static int __devinit clock_probe(struct of_device *op, const struct of_device_id
771 return 0; 598 return 0;
772} 599}
773 600
774static struct of_device_id clock_match[] = { 601static struct of_device_id rtc_match[] = {
775 { 602 {
776 .name = "eeprom", 603 .name = "rtc",
604 },
605 {},
606};
607
608static struct of_platform_driver rtc_driver = {
609 .match_table = rtc_match,
610 .probe = rtc_probe,
611 .driver = {
612 .name = "rtc",
777 }, 613 },
614};
615
616static unsigned char mostek_read_byte(struct device *dev, u32 ofs)
617{
618 struct platform_device *pdev = to_platform_device(dev);
619 void __iomem *regs;
620 unsigned char val;
621
622 regs = (void __iomem *) pdev->resource[0].start;
623 val = readb(regs + ofs);
624
625 /* the year 0 is 1968 */
626 if (ofs == M48T59_YEAR) {
627 val += 0x68;
628 if ((val & 0xf) > 9)
629 val += 6;
630 }
631 return val;
632}
633
634static void mostek_write_byte(struct device *dev, u32 ofs, u8 val)
635{
636 struct platform_device *pdev = to_platform_device(dev);
637 void __iomem *regs;
638
639 regs = (void __iomem *) pdev->resource[0].start;
640 if (ofs == M48T59_YEAR) {
641 if (val < 0x68)
642 val += 0x32;
643 else
644 val -= 0x68;
645 if ((val & 0xf) > 9)
646 val += 6;
647 if ((val & 0xf0) > 0x9A)
648 val += 0x60;
649 }
650 writeb(val, regs + ofs);
651}
652
653static struct m48t59_plat_data m48t59_data = {
654 .read_byte = mostek_read_byte,
655 .write_byte = mostek_write_byte,
656};
657
658static struct platform_device m48t59_rtc = {
659 .name = "rtc-m48t59",
660 .id = 0,
661 .num_resources = 1,
662 .dev = {
663 .platform_data = &m48t59_data,
664 },
665};
666
667static int __devinit mostek_probe(struct of_device *op, const struct of_device_id *match)
668{
669 struct device_node *dp = op->node;
670
671 /* On an Enterprise system there can be multiple mostek clocks.
672 * We should only match the one that is on the central FHC bus.
673 */
674 if (!strcmp(dp->parent->name, "fhc") &&
675 strcmp(dp->parent->parent->name, "central") != 0)
676 return -ENODEV;
677
678 printk(KERN_INFO "%s: Mostek regs at 0x%lx\n",
679 dp->full_name, op->resource[0].start);
680
681 m48t59_rtc.resource = &op->resource[0];
682 return platform_device_register(&m48t59_rtc);
683}
684
685static struct of_device_id mostek_match[] = {
778 { 686 {
779 .name = "rtc", 687 .name = "eeprom",
780 }, 688 },
781 {}, 689 {},
782}; 690};
783 691
784static struct of_platform_driver clock_driver = { 692static struct of_platform_driver mostek_driver = {
785 .match_table = clock_match, 693 .match_table = mostek_match,
786 .probe = clock_probe, 694 .probe = mostek_probe,
787 .driver = { 695 .driver = {
788 .name = "clock", 696 .name = "mostek",
789 }, 697 },
790}; 698};
791 699
@@ -806,7 +714,10 @@ static int __init clock_init(void)
806 return 0; 714 return 0;
807 } 715 }
808 716
809 return of_register_driver(&clock_driver, &of_platform_bus_type); 717 (void) of_register_driver(&rtc_driver, &of_platform_bus_type);
718 (void) of_register_driver(&mostek_driver, &of_platform_bus_type);
719
720 return 0;
810} 721}
811 722
812/* Must be after subsys_initcall() so that busses are probed. Must 723/* Must be after subsys_initcall() so that busses are probed. Must
@@ -1078,7 +989,6 @@ unsigned long long sched_clock(void)
1078static int set_rtc_mmss(unsigned long nowtime) 989static int set_rtc_mmss(unsigned long nowtime)
1079{ 990{
1080 int real_seconds, real_minutes, chip_minutes; 991 int real_seconds, real_minutes, chip_minutes;
1081 void __iomem *mregs = mstk48t02_regs;
1082#ifdef CONFIG_PCI 992#ifdef CONFIG_PCI
1083 unsigned long dregs = ds1287_regs; 993 unsigned long dregs = ds1287_regs;
1084 void __iomem *bregs = bq4802_regs; 994 void __iomem *bregs = bq4802_regs;
@@ -1087,62 +997,15 @@ static int set_rtc_mmss(unsigned long nowtime)
1087 void __iomem *bregs = 0UL; 997 void __iomem *bregs = 0UL;
1088#endif 998#endif
1089 unsigned long flags; 999 unsigned long flags;
1090 u8 tmp;
1091 1000
1092 /* 1001 /*
1093 * Not having a register set can lead to trouble. 1002 * Not having a register set can lead to trouble.
1094 * Also starfire doesn't have a tod clock. 1003 * Also starfire doesn't have a tod clock.
1095 */ 1004 */
1096 if (!mregs && !dregs && !bregs) 1005 if (!dregs && !bregs)
1097 return -1; 1006 return -1;
1098 1007
1099 if (mregs) { 1008 if (bregs) {
1100 spin_lock_irqsave(&mostek_lock, flags);
1101
1102 /* Read the current RTC minutes. */
1103 tmp = mostek_read(mregs + MOSTEK_CREG);
1104 tmp |= MSTK_CREG_READ;
1105 mostek_write(mregs + MOSTEK_CREG, tmp);
1106
1107 chip_minutes = MSTK_REG_MIN(mregs);
1108
1109 tmp = mostek_read(mregs + MOSTEK_CREG);
1110 tmp &= ~MSTK_CREG_READ;
1111 mostek_write(mregs + MOSTEK_CREG, tmp);
1112
1113 /*
1114 * since we're only adjusting minutes and seconds,
1115 * don't interfere with hour overflow. This avoids
1116 * messing with unknown time zones but requires your
1117 * RTC not to be off by more than 15 minutes
1118 */
1119 real_seconds = nowtime % 60;
1120 real_minutes = nowtime / 60;
1121 if (((abs(real_minutes - chip_minutes) + 15)/30) & 1)
1122 real_minutes += 30; /* correct for half hour time zone */
1123 real_minutes %= 60;
1124
1125 if (abs(real_minutes - chip_minutes) < 30) {
1126 tmp = mostek_read(mregs + MOSTEK_CREG);
1127 tmp |= MSTK_CREG_WRITE;
1128 mostek_write(mregs + MOSTEK_CREG, tmp);
1129
1130 MSTK_SET_REG_SEC(mregs,real_seconds);
1131 MSTK_SET_REG_MIN(mregs,real_minutes);
1132
1133 tmp = mostek_read(mregs + MOSTEK_CREG);
1134 tmp &= ~MSTK_CREG_WRITE;
1135 mostek_write(mregs + MOSTEK_CREG, tmp);
1136
1137 spin_unlock_irqrestore(&mostek_lock, flags);
1138
1139 return 0;
1140 } else {
1141 spin_unlock_irqrestore(&mostek_lock, flags);
1142
1143 return -1;
1144 }
1145 } else if (bregs) {
1146 int retval = 0; 1009 int retval = 0;
1147 unsigned char val = readb(bregs + 0x0e); 1010 unsigned char val = readb(bregs + 0x0e);
1148 1011
@@ -1485,74 +1348,6 @@ static int cmos_set_rtc_time(struct rtc_time *rtc_tm)
1485} 1348}
1486#endif /* CONFIG_PCI */ 1349#endif /* CONFIG_PCI */
1487 1350
1488static void mostek_get_rtc_time(struct rtc_time *rtc_tm)
1489{
1490 void __iomem *regs = mstk48t02_regs;
1491 u8 tmp;
1492
1493 spin_lock_irq(&mostek_lock);
1494
1495 tmp = mostek_read(regs + MOSTEK_CREG);
1496 tmp |= MSTK_CREG_READ;
1497 mostek_write(regs + MOSTEK_CREG, tmp);
1498
1499 rtc_tm->tm_sec = MSTK_REG_SEC(regs);
1500 rtc_tm->tm_min = MSTK_REG_MIN(regs);
1501 rtc_tm->tm_hour = MSTK_REG_HOUR(regs);
1502 rtc_tm->tm_mday = MSTK_REG_DOM(regs);
1503 rtc_tm->tm_mon = MSTK_REG_MONTH(regs);
1504 rtc_tm->tm_year = MSTK_CVT_YEAR( MSTK_REG_YEAR(regs) );
1505 rtc_tm->tm_wday = MSTK_REG_DOW(regs);
1506
1507 tmp = mostek_read(regs + MOSTEK_CREG);
1508 tmp &= ~MSTK_CREG_READ;
1509 mostek_write(regs + MOSTEK_CREG, tmp);
1510
1511 spin_unlock_irq(&mostek_lock);
1512
1513 rtc_tm->tm_mon--;
1514 rtc_tm->tm_wday--;
1515 rtc_tm->tm_year -= 1900;
1516}
1517
1518static int mostek_set_rtc_time(struct rtc_time *rtc_tm)
1519{
1520 unsigned char mon, day, hrs, min, sec, wday;
1521 void __iomem *regs = mstk48t02_regs;
1522 unsigned int yrs;
1523 u8 tmp;
1524
1525 yrs = rtc_tm->tm_year + 1900;
1526 mon = rtc_tm->tm_mon + 1;
1527 day = rtc_tm->tm_mday;
1528 wday = rtc_tm->tm_wday + 1;
1529 hrs = rtc_tm->tm_hour;
1530 min = rtc_tm->tm_min;
1531 sec = rtc_tm->tm_sec;
1532
1533 spin_lock_irq(&mostek_lock);
1534
1535 tmp = mostek_read(regs + MOSTEK_CREG);
1536 tmp |= MSTK_CREG_WRITE;
1537 mostek_write(regs + MOSTEK_CREG, tmp);
1538
1539 MSTK_SET_REG_SEC(regs, sec);
1540 MSTK_SET_REG_MIN(regs, min);
1541 MSTK_SET_REG_HOUR(regs, hrs);
1542 MSTK_SET_REG_DOW(regs, wday);
1543 MSTK_SET_REG_DOM(regs, day);
1544 MSTK_SET_REG_MONTH(regs, mon);
1545 MSTK_SET_REG_YEAR(regs, yrs - MSTK_YEAR_ZERO);
1546
1547 tmp = mostek_read(regs + MOSTEK_CREG);
1548 tmp &= ~MSTK_CREG_WRITE;
1549 mostek_write(regs + MOSTEK_CREG, tmp);
1550
1551 spin_unlock_irq(&mostek_lock);
1552
1553 return 0;
1554}
1555
1556struct mini_rtc_ops { 1351struct mini_rtc_ops {
1557 void (*get_rtc_time)(struct rtc_time *); 1352 void (*get_rtc_time)(struct rtc_time *);
1558 int (*set_rtc_time)(struct rtc_time *); 1353 int (*set_rtc_time)(struct rtc_time *);
@@ -1580,11 +1375,6 @@ static struct mini_rtc_ops cmos_rtc_ops = {
1580}; 1375};
1581#endif /* CONFIG_PCI */ 1376#endif /* CONFIG_PCI */
1582 1377
1583static struct mini_rtc_ops mostek_rtc_ops = {
1584 .get_rtc_time = mostek_get_rtc_time,
1585 .set_rtc_time = mostek_set_rtc_time,
1586};
1587
1588static struct mini_rtc_ops *mini_rtc_ops; 1378static struct mini_rtc_ops *mini_rtc_ops;
1589 1379
1590static inline void mini_get_rtc_time(struct rtc_time *time) 1380static inline void mini_get_rtc_time(struct rtc_time *time)
@@ -1717,8 +1507,6 @@ static int __init rtc_mini_init(void)
1717 else if (ds1287_regs) 1507 else if (ds1287_regs)
1718 mini_rtc_ops = &cmos_rtc_ops; 1508 mini_rtc_ops = &cmos_rtc_ops;
1719#endif /* CONFIG_PCI */ 1509#endif /* CONFIG_PCI */
1720 else if (mstk48t02_regs)
1721 mini_rtc_ops = &mostek_rtc_ops;
1722 else 1510 else
1723 return -ENODEV; 1511 return -ENODEV;
1724 1512