diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2007-07-19 13:59:58 -0700 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-07-20 17:15:48 -0700 |
commit | cdee99d7461d928815db6219fb14d37f99241d44 (patch) | |
tree | 8db5fb8f4d06171f998d19d25980c50205bfb03d | |
parent | 0fe85d504b47267bcdb25a563c535aa2ae075ff4 (diff) |
[SPARC64]: Stop using drivers/char/rtc.c
The existing sparc64 mini_rtc driver can handle CMOS based
rtcs trivially with just a few lines of code and the simplifies
things tremendously.
Tested on SB1500.
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | arch/sparc64/kernel/time.c | 79 | ||||
-rw-r--r-- | drivers/char/Kconfig | 2 | ||||
-rw-r--r-- | drivers/char/rtc.c | 30 |
3 files changed, 86 insertions, 25 deletions
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index 592ffcd5760..e340eb401fb 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c @@ -1434,6 +1434,78 @@ static int bq4802_set_rtc_time(struct rtc_time *time) return 0; } + +static void cmos_get_rtc_time(struct rtc_time *rtc_tm) +{ + unsigned char ctrl; + + rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS); + rtc_tm->tm_min = CMOS_READ(RTC_MINUTES); + rtc_tm->tm_hour = CMOS_READ(RTC_HOURS); + rtc_tm->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH); + rtc_tm->tm_mon = CMOS_READ(RTC_MONTH); + rtc_tm->tm_year = CMOS_READ(RTC_YEAR); + rtc_tm->tm_wday = CMOS_READ(RTC_DAY_OF_WEEK); + + ctrl = CMOS_READ(RTC_CONTROL); + if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + BCD_TO_BIN(rtc_tm->tm_sec); + BCD_TO_BIN(rtc_tm->tm_min); + BCD_TO_BIN(rtc_tm->tm_hour); + BCD_TO_BIN(rtc_tm->tm_mday); + BCD_TO_BIN(rtc_tm->tm_mon); + BCD_TO_BIN(rtc_tm->tm_year); + BCD_TO_BIN(rtc_tm->tm_wday); + } + + if (rtc_tm->tm_year <= 69) + rtc_tm->tm_year += 100; + + rtc_tm->tm_mon--; +} + +static int cmos_set_rtc_time(struct rtc_time *rtc_tm) +{ + unsigned char mon, day, hrs, min, sec; + unsigned char save_control, save_freq_select; + unsigned int yrs; + + yrs = rtc_tm->tm_year; + mon = rtc_tm->tm_mon + 1; + day = rtc_tm->tm_mday; + hrs = rtc_tm->tm_hour; + min = rtc_tm->tm_min; + sec = rtc_tm->tm_sec; + + if (yrs >= 100) + yrs -= 100; + + if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + BIN_TO_BCD(sec); + BIN_TO_BCD(min); + BIN_TO_BCD(hrs); + BIN_TO_BCD(day); + BIN_TO_BCD(mon); + BIN_TO_BCD(yrs); + } + + save_control = CMOS_READ(RTC_CONTROL); + CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); + save_freq_select = CMOS_READ(RTC_FREQ_SELECT); + CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); + + CMOS_WRITE(yrs, RTC_YEAR); + CMOS_WRITE(mon, RTC_MONTH); + CMOS_WRITE(day, RTC_DAY_OF_MONTH); + CMOS_WRITE(hrs, RTC_HOURS); + CMOS_WRITE(min, RTC_MINUTES); + CMOS_WRITE(sec, RTC_SECONDS); + + CMOS_WRITE(save_control, RTC_CONTROL); + CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); + + return 0; +} #endif /* CONFIG_PCI */ struct mini_rtc_ops { @@ -1456,6 +1528,11 @@ static struct mini_rtc_ops bq4802_rtc_ops = { .get_rtc_time = bq4802_get_rtc_time, .set_rtc_time = bq4802_set_rtc_time, }; + +static struct mini_rtc_ops cmos_rtc_ops = { + .get_rtc_time = cmos_get_rtc_time, + .set_rtc_time = cmos_set_rtc_time, +}; #endif /* CONFIG_PCI */ static struct mini_rtc_ops *mini_rtc_ops; @@ -1583,6 +1660,8 @@ static int __init rtc_mini_init(void) #ifdef CONFIG_PCI else if (bq4802_regs) mini_rtc_ops = &bq4802_rtc_ops; + else if (ds1287_regs) + mini_rtc_ops = &cmos_rtc_ops; #endif /* CONFIG_PCI */ else return -ENODEV; diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 4373d7cdc5d..c8dfd18bea4 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -726,7 +726,7 @@ config NVRAM config RTC tristate "Enhanced Real Time Clock Support" - depends on !PPC && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV && !ARM && !SUPERH && !S390 + depends on !PPC && !PARISC && !IA64 && !M68K && !SPARC64 && (!SPARC32 || PCI) && !FRV && !ARM && !SUPERH && !S390 ---help--- If you say Y here and create a character special file /dev/rtc with major number 10 and minor number 135 using mknod ("man mknod"), you diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index 22cf7aa56cc..30c3f54c766 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c @@ -86,12 +86,9 @@ #include <asm/hpet.h> #endif -#ifdef __sparc__ +#ifdef CONFIG_SPARC32 #include <linux/pci.h> #include <asm/ebus.h> -#ifdef __sparc_v9__ -#include <asm/isa.h> -#endif static unsigned long rtc_port; static int rtc_irq = PCI_IRQ_NONE; @@ -930,13 +927,9 @@ static int __init rtc_init(void) unsigned int year, ctrl; char *guess = NULL; #endif -#ifdef __sparc__ +#ifdef CONFIG_SPARC32 struct linux_ebus *ebus; struct linux_ebus_device *edev; -#ifdef __sparc_v9__ - struct sparc_isa_bridge *isa_br; - struct sparc_isa_device *isa_dev; -#endif #else void *r; #ifdef RTC_IRQ @@ -944,7 +937,7 @@ static int __init rtc_init(void) #endif #endif -#ifdef __sparc__ +#ifdef CONFIG_SPARC32 for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { if(strcmp(edev->prom_node->name, "rtc") == 0) { @@ -954,17 +947,6 @@ static int __init rtc_init(void) } } } -#ifdef __sparc_v9__ - for_each_isa(isa_br) { - for_each_isadev(isa_dev, isa_br) { - if (strcmp(isa_dev->prom_node->name, "rtc") == 0) { - rtc_port = isa_dev->resource.start; - rtc_irq = isa_dev->irq; - goto found; - } - } - } -#endif rtc_has_irq = 0; printk(KERN_ERR "rtc_init: no PC rtc found\n"); return -EIO; @@ -1020,7 +1002,7 @@ no_irq: #endif -#endif /* __sparc__ vs. others */ +#endif /* CONFIG_SPARC32 vs. others */ if (misc_register(&rtc_dev)) { #ifdef RTC_IRQ @@ -1105,7 +1087,7 @@ static void __exit rtc_exit (void) remove_proc_entry ("driver/rtc", NULL); misc_deregister(&rtc_dev); -#ifdef __sparc__ +#ifdef CONFIG_SPARC32 if (rtc_has_irq) free_irq (rtc_irq, &rtc_port); #else @@ -1117,7 +1099,7 @@ static void __exit rtc_exit (void) if (rtc_has_irq) free_irq (RTC_IRQ, NULL); #endif -#endif /* __sparc__ */ +#endif /* CONFIG_SPARC32 */ } module_init(rtc_init); |