diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-12-24 15:52:44 +0300 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-12-24 16:39:18 +0300 |
commit | 382b4480ff832e472d76c99f3f75fffb30e118c0 (patch) | |
tree | caddb10180a24cda8b0ed280688dde14dcb7232e /arch/arm/mach-footbridge | |
parent | 6dc995a3da9adfa83d61ccf06aa1afa5f6ab764f (diff) | |
download | linux-382b4480ff832e472d76c99f3f75fffb30e118c0.tar.xz |
ARM: footbridge: trim down old ISA rtc setup
This fixes a "start_kernel(): bug: interrupts were enabled early".
rtc_cmos now takes care of initializing the ISA RTC and reading the
current time and date from it; there's no need to repeat that here,
thereby causing interrupts to be enabled too early.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-footbridge')
-rw-r--r-- | arch/arm/mach-footbridge/Makefile | 4 | ||||
-rw-r--r-- | arch/arm/mach-footbridge/dc21285-timer.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-footbridge/isa-rtc.c | 57 | ||||
-rw-r--r-- | arch/arm/mach-footbridge/isa-timer.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-footbridge/isa.c | 18 | ||||
-rw-r--r-- | arch/arm/mach-footbridge/time.c | 164 |
6 files changed, 73 insertions, 174 deletions
diff --git a/arch/arm/mach-footbridge/Makefile b/arch/arm/mach-footbridge/Makefile index 32f8609e4f85..3afb1b25946f 100644 --- a/arch/arm/mach-footbridge/Makefile +++ b/arch/arm/mach-footbridge/Makefile @@ -4,7 +4,7 @@ # Object file lists. -obj-y := common.o dc21285.o dma.o isa-irq.o time.o +obj-y := common.o dc21285.o dma.o isa-irq.o obj-m := obj-n := obj- := @@ -25,4 +25,4 @@ obj-$(CONFIG_ARCH_PERSONAL_SERVER) += personal.o dc21285-timer.o obj-$(CONFIG_PCI) +=$(pci-y) obj-$(CONFIG_LEDS) +=$(leds-y) -obj-$(CONFIG_ISA) += isa.o +obj-$(CONFIG_ISA) += isa.o isa-rtc.o diff --git a/arch/arm/mach-footbridge/dc21285-timer.c b/arch/arm/mach-footbridge/dc21285-timer.c index da35bc5c5ccc..bc5e83fb5819 100644 --- a/arch/arm/mach-footbridge/dc21285-timer.c +++ b/arch/arm/mach-footbridge/dc21285-timer.c @@ -56,8 +56,6 @@ static void __init footbridge_timer_init(void) *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16; setup_irq(IRQ_TIMER1, &footbridge_timer_irq); - - isa_rtc_init(); } struct sys_timer footbridge_timer = { diff --git a/arch/arm/mach-footbridge/isa-rtc.c b/arch/arm/mach-footbridge/isa-rtc.c new file mode 100644 index 000000000000..07fde4051f78 --- /dev/null +++ b/arch/arm/mach-footbridge/isa-rtc.c @@ -0,0 +1,57 @@ +/* + * arch/arm/mach-footbridge/isa-rtc.c + * + * Copyright (C) 1998 Russell King. + * Copyright (C) 1998 Phil Blundell + * + * CATS has a real-time clock, though the evaluation board doesn't. + * + * Changelog: + * 21-Mar-1998 RMK Created + * 27-Aug-1998 PJB CATS support + * 28-Dec-1998 APH Made leds optional + * 20-Jan-1999 RMK Started merge of EBSA285, CATS and NetWinder + * 16-Mar-1999 RMK More support for EBSA285-like machines with RTCs in + */ + +#define RTC_PORT(x) (0x70+(x)) +#define RTC_ALWAYS_BCD 0 + +#include <linux/init.h> +#include <linux/mc146818rtc.h> +#include <linux/bcd.h> +#include <linux/io.h> + +#include "common.h" + +void __init isa_rtc_init(void) +{ + int reg_d, reg_b; + + /* + * Probe for the RTC. + */ + reg_d = CMOS_READ(RTC_REG_D); + + /* + * make sure the divider is set + */ + CMOS_WRITE(RTC_REF_CLCK_32KHZ, RTC_REG_A); + + /* + * Set control reg B + * (24 hour mode, update enabled) + */ + reg_b = CMOS_READ(RTC_REG_B) & 0x7f; + reg_b |= 2; + CMOS_WRITE(reg_b, RTC_REG_B); + + if ((CMOS_READ(RTC_REG_A) & 0x7f) == RTC_REF_CLCK_32KHZ && + CMOS_READ(RTC_REG_B) == reg_b) { + /* + * We have a RTC. Check the battery + */ + if ((reg_d & 0x80) == 0) + printk(KERN_WARNING "RTC: *** warning: CMOS battery bad\n"); + } +} diff --git a/arch/arm/mach-footbridge/isa-timer.c b/arch/arm/mach-footbridge/isa-timer.c index 0c8390082fa8..f488fa2082d7 100644 --- a/arch/arm/mach-footbridge/isa-timer.c +++ b/arch/arm/mach-footbridge/isa-timer.c @@ -76,8 +76,6 @@ static struct irqaction isa_timer_irq = { static void __init isa_timer_init(void) { - isa_rtc_init(); - /* enable PIT timer */ /* set for periodic (4) and LSB/MSB write (0x30) */ outb(0x34, 0x43); diff --git a/arch/arm/mach-footbridge/isa.c b/arch/arm/mach-footbridge/isa.c index 725a219d0ed5..4d9276c27d6f 100644 --- a/arch/arm/mach-footbridge/isa.c +++ b/arch/arm/mach-footbridge/isa.c @@ -11,6 +11,9 @@ #include <linux/serial_8250.h> #include <asm/irq.h> +#include <asm/hardware/dec21285.h> + +#include "common.h" static struct resource rtc_resources[] = { [0] = { @@ -77,11 +80,18 @@ static struct platform_device serial_device = { static int __init footbridge_isa_init(void) { - int err; + int err = 0; - err = platform_device_register(&rtc_device); - if (err) - printk(KERN_ERR "Unable to register RTC device: %d\n", err); + if (!footbridge_cfn_mode()) + return 0; + + /* Personal server doesn't have RTC */ + if (!machine_is_personal_server()) { + isa_rtc_init(); + err = platform_device_register(&rtc_device); + if (err) + printk(KERN_ERR "Unable to register RTC device: %d\n", err); + } err = platform_device_register(&serial_device); if (err) printk(KERN_ERR "Unable to register serial device: %d\n", err); diff --git a/arch/arm/mach-footbridge/time.c b/arch/arm/mach-footbridge/time.c deleted file mode 100644 index cd1b54ff9fe2..000000000000 --- a/arch/arm/mach-footbridge/time.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * arch/arm/mach-footbridge/include/mach/time.h - * - * Copyright (C) 1998 Russell King. - * Copyright (C) 1998 Phil Blundell - * - * CATS has a real-time clock, though the evaluation board doesn't. - * - * Changelog: - * 21-Mar-1998 RMK Created - * 27-Aug-1998 PJB CATS support - * 28-Dec-1998 APH Made leds optional - * 20-Jan-1999 RMK Started merge of EBSA285, CATS and NetWinder - * 16-Mar-1999 RMK More support for EBSA285-like machines with RTCs in - */ - -#define RTC_PORT(x) (rtc_base+(x)) -#define RTC_ALWAYS_BCD 0 - -#include <linux/timex.h> -#include <linux/init.h> -#include <linux/sched.h> -#include <linux/mc146818rtc.h> -#include <linux/bcd.h> -#include <linux/io.h> - -#include <mach/hardware.h> - -#include <asm/mach/time.h> -#include "common.h" - -static int rtc_base; - -static unsigned long __init get_isa_cmos_time(void) -{ - unsigned int year, mon, day, hour, min, sec; - - // check to see if the RTC makes sense..... - if ((CMOS_READ(RTC_VALID) & RTC_VRT) == 0) - return mktime(1970, 1, 1, 0, 0, 0); - - do { - sec = CMOS_READ(RTC_SECONDS); - min = CMOS_READ(RTC_MINUTES); - hour = CMOS_READ(RTC_HOURS); - day = CMOS_READ(RTC_DAY_OF_MONTH); - mon = CMOS_READ(RTC_MONTH); - year = CMOS_READ(RTC_YEAR); - } while (sec != CMOS_READ(RTC_SECONDS)); - - if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - sec = bcd2bin(sec); - min = bcd2bin(min); - hour = bcd2bin(hour); - day = bcd2bin(day); - mon = bcd2bin(mon); - year = bcd2bin(year); - } - if ((year += 1900) < 1970) - year += 100; - return mktime(year, mon, day, hour, min, sec); -} - -static int set_isa_cmos_time(void) -{ - int retval = 0; - int real_seconds, real_minutes, cmos_minutes; - unsigned char save_control, save_freq_select; - unsigned long nowtime = xtime.tv_sec; - - save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */ - CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); - - save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */ - CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); - - cmos_minutes = CMOS_READ(RTC_MINUTES); - if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) - cmos_minutes = bcd2bin(cmos_minutes); - - /* - * since we're only adjusting minutes and seconds, - * don't interfere with hour overflow. This avoids - * messing with unknown time zones but requires your - * RTC not to be off by more than 15 minutes - */ - real_seconds = nowtime % 60; - real_minutes = nowtime / 60; - if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) - real_minutes += 30; /* correct for half hour time zone */ - real_minutes %= 60; - - if (abs(real_minutes - cmos_minutes) < 30) { - if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - real_seconds = bin2bcd(real_seconds); - real_minutes = bin2bcd(real_minutes); - } - CMOS_WRITE(real_seconds,RTC_SECONDS); - CMOS_WRITE(real_minutes,RTC_MINUTES); - } else - retval = -1; - - /* The following flags have to be released exactly in this order, - * otherwise the DS12887 (popular MC146818A clone with integrated - * battery and quartz) will not reset the oscillator and will not - * update precisely 500 ms later. You won't find this mentioned in - * the Dallas Semiconductor data sheets, but who believes data - * sheets anyway ... -- Markus Kuhn - */ - CMOS_WRITE(save_control, RTC_CONTROL); - CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); - - return retval; -} - -void __init isa_rtc_init(void) -{ - if (machine_is_personal_server()) - /* - * Add-in 21285s shouldn't access the RTC - */ - rtc_base = 0; - else - rtc_base = 0x70; - - if (rtc_base) { - int reg_d, reg_b; - - /* - * Probe for the RTC. - */ - reg_d = CMOS_READ(RTC_REG_D); - - /* - * make sure the divider is set - */ - CMOS_WRITE(RTC_REF_CLCK_32KHZ, RTC_REG_A); - - /* - * Set control reg B - * (24 hour mode, update enabled) - */ - reg_b = CMOS_READ(RTC_REG_B) & 0x7f; - reg_b |= 2; - CMOS_WRITE(reg_b, RTC_REG_B); - - if ((CMOS_READ(RTC_REG_A) & 0x7f) == RTC_REF_CLCK_32KHZ && - CMOS_READ(RTC_REG_B) == reg_b) { - struct timespec tv; - - /* - * We have a RTC. Check the battery - */ - if ((reg_d & 0x80) == 0) - printk(KERN_WARNING "RTC: *** warning: CMOS battery bad\n"); - - tv.tv_nsec = 0; - tv.tv_sec = get_isa_cmos_time(); - do_settimeofday(&tv); - set_rtc = set_isa_cmos_time; - } else - rtc_base = 0; - } -} |