diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-12-06 23:51:34 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1997-12-06 23:51:34 +0000 |
commit | 230e5ab6a084ed50470f101934782dbf54b0d06b (patch) | |
tree | 5dd821c8d33f450470588e7a543f74bf74306e9e /arch/alpha/kernel | |
parent | c9b1c8a64c6444d189856f1e26bdcb8b4cd0113a (diff) |
Merge with Linux 2.1.67.
Diffstat (limited to 'arch/alpha/kernel')
-rw-r--r-- | arch/alpha/kernel/entry.S | 3 | ||||
-rw-r--r-- | arch/alpha/kernel/irq.c | 25 | ||||
-rw-r--r-- | arch/alpha/kernel/time.c | 58 |
3 files changed, 53 insertions, 33 deletions
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index e22313036..75c0665a7 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S @@ -10,7 +10,7 @@ #define rti .long PAL_rti #define SIGCHLD 20 -#define NR_SYSCALLS 350 +#define NR_SYSCALLS 352 #define osf_vfork sys_fork /* @@ -771,4 +771,5 @@ sys_call_table: .quad sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, do_entSys /* sys_afs_syscall */, sys_newuname .quad sys_nanosleep, sys_mremap, sys_nfsservctl, sys_setresuid, sys_getresuid .quad sys_pciconfig_read, sys_pciconfig_write, sys_query_module + .quad sys_prctl, sys_pread, sys_pwrite .quad do_entSys, do_entSys diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c index 133c27828..3291f4603 100644 --- a/arch/alpha/kernel/irq.c +++ b/arch/alpha/kernel/irq.c @@ -37,6 +37,18 @@ # error Unable to handle more than 64 irq levels. #endif +/* PROBE_MASK is the bitset of irqs that we consider for autoprobing: */ +#if defined(CONFIG_ALPHA_P2K) + /* always mask out unused timer irq 0 and RTC irq 8 */ +# define PROBE_MASK (((1UL << NR_IRQS) - 1) & ~0x101UL) +#elif defined(CONFIG_ALPHA_ALCOR) + /* always mask out unused timer irq 0, "irqs" 20-30, and the EISA cascade: */ +# define PROBE_MASK (((1UL << NR_IRQS) - 1) & ~0xfff000000001UL) +#else + /* always mask out unused timer irq 0: */ +# define PROBE_MASK (((1UL << NR_IRQS) - 1) & ~1UL) +#endif + /* Reserved interrupts. These must NEVER be requested by any driver! */ #define IS_RESERVED_IRQ(irq) ((irq)==2) /* IRQ 2 used by hw cascade */ @@ -644,10 +656,13 @@ unsigned long probe_irq_on(void) unsigned int i; for (i = NR_IRQS - 1; i > 0; i--) { + if (!(PROBE_MASK & (1UL << i))) { + continue; + } action = irq_action[i]; if (!action) { enable_irq(i); - irqs |= (1 << i); + irqs |= (1UL << i); } } /* @@ -668,14 +683,10 @@ unsigned long probe_irq_on(void) */ int probe_irq_off(unsigned long irqs) { + unsigned long delay; int i; - /* as irq 0 & 8 handling don't use this function, i didn't - * bother changing the following: */ - irqs &= irq_mask & ~1; /* always mask out irq 0---it's the unused timer */ -#ifdef CONFIG_ALPHA_P2K - irqs &= ~(1 << 8); /* mask out irq 8 since that's the unused RTC input to PIC */ -#endif + irqs &= irq_mask; if (!irqs) return 0; i = ffz(~irqs); diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index b289d4f82..2b0870c3b 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c @@ -12,6 +12,10 @@ * precision CMOS clock update * 1997-01-09 Adrian Sun * use interval timer if CONFIG_RTC=y + * 1997-10-29 John Bowman (bowman@math.ualberta.ca) + * fixed tick loss calculation in timer_interrupt + * (round system clock to nearest tick instead of truncating) + * fixed algorithm in time_init for getting time from CMOS clock */ #include <linux/errno.h> #include <linux/sched.h> @@ -23,6 +27,7 @@ #include <asm/uaccess.h> #include <asm/io.h> #include <asm/hwrpb.h> +#include <asm/delay.h> #include <linux/mc146818rtc.h> #include <linux/timex.h> @@ -48,7 +53,6 @@ static int set_rtc_mmss(unsigned long); /* lump static variables together for more efficient access: */ static struct { __u32 last_time; /* cycle counter last time it got invoked */ - __u32 max_cycles_per_tick; /* more makes us think we lost an interrupt */ unsigned long scaled_ticks_per_cycle; /* ticks/cycle * 2^48 */ long last_rtc_update; /* last time the cmos clock got updated */ } state; @@ -70,19 +74,20 @@ static inline __u32 rpcc(void) void timer_interrupt(int irq, void *dev, struct pt_regs * regs) { __u32 delta, now; + int i, nticks; now = rpcc(); delta = now - state.last_time; state.last_time = now; - if (delta > state.max_cycles_per_tick) { - int i, missed_ticks; - - missed_ticks = ((delta * state.scaled_ticks_per_cycle) >> FIX_SHIFT) - 1; - for (i = 0; i < missed_ticks; ++i) { - do_timer(regs); - } + if(hwrpb->cycle_freq) { + nticks = (delta * state.scaled_ticks_per_cycle) >> (FIX_SHIFT-1); + nticks = (nticks+1) >> 1; + } + else nticks=1; /* No way to estimate lost ticks if we don't know + the cycle frequency. */ + for (i = 0; i < nticks; ++i) { + do_timer(regs); } - do_timer(regs); /* * If we have an externally synchronized Linux clock, then update @@ -136,7 +141,6 @@ void time_init(void) #endif void (*irq_handler)(int, void *, struct pt_regs *); unsigned int year, mon, day, hour, min, sec; - int i; /* The Linux interpretation of the CMOS clock register contents: * When the Update-In-Progress (UIP) flag goes from 1 to 0, the @@ -144,20 +148,24 @@ void time_init(void) * Let's hope other operating systems interpret the RTC the same way. */ /* read RTC exactly on falling edge of update flag */ - for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */ - if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) - break; - for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */ - if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) - break; - do { /* Isn't this overkill ? UIP above should guarantee consistency */ - 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)); + /* Wait for rise.... (may take up to 1 second) */ + + do {} while(!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)); + +/* Jay Estabook <jestabro@amt.tay1.dec.com>: + * Wait for the Update Done Interrupt bit (0x10) in reg C (12) to be set, + * which (hopefully) indicates that the update is really done. + */ + + do {} while(!CMOS_READ(RTC_REG_C) & RTC_UIP); + + 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); + if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { BCD_TO_BIN(sec); @@ -185,8 +193,8 @@ void time_init(void) __you_loose(); } state.last_time = rpcc(); + if(hwrpb->cycle_freq) state.scaled_ticks_per_cycle = ((unsigned long) HZ << FIX_SHIFT) / hwrpb->cycle_freq; - state.max_cycles_per_tick = (2 * hwrpb->cycle_freq) / HZ; state.last_rtc_update = 0; #ifdef CONFIG_RTC |