summaryrefslogtreecommitdiffstats
path: root/arch/alpha/kernel
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-12-06 23:51:34 +0000
committerRalf Baechle <ralf@linux-mips.org>1997-12-06 23:51:34 +0000
commit230e5ab6a084ed50470f101934782dbf54b0d06b (patch)
tree5dd821c8d33f450470588e7a543f74bf74306e9e /arch/alpha/kernel
parentc9b1c8a64c6444d189856f1e26bdcb8b4cd0113a (diff)
Merge with Linux 2.1.67.
Diffstat (limited to 'arch/alpha/kernel')
-rw-r--r--arch/alpha/kernel/entry.S3
-rw-r--r--arch/alpha/kernel/irq.c25
-rw-r--r--arch/alpha/kernel/time.c58
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