time.c 7.3 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/*
 *  linux/arch/parisc/kernel/time.c
 *
 *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
 *  Modifications for ARM (C) 1994, 1995, 1996,1997 Russell King
 *  Copyright (C) 1999 SuSE GmbH, (Philipp Rumpf, prumpf@tux.org)
 *
 * 1994-07-02  Alan Modra
 *             fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
 * 1998-12-20  Updated NTP code according to technical memorandum Jan '96
 *             "A Kernel Model for Precision Timekeeping" by Dave Mills
 */
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/time.h>
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/profile.h>
25
#include <linux/clocksource.h>
26
#include <linux/platform_device.h>
27
#include <linux/ftrace.h>
L
Linus Torvalds 已提交
28 29 30 31

#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/irq.h>
32
#include <asm/page.h>
L
Linus Torvalds 已提交
33 34 35 36 37 38
#include <asm/param.h>
#include <asm/pdc.h>
#include <asm/led.h>

#include <linux/timex.h>

39
static unsigned long clocktick __read_mostly;	/* timer cycles per tick */
L
Linus Torvalds 已提交
40

41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
/*
 * We keep time on PA-RISC Linux by using the Interval Timer which is
 * a pair of registers; one is read-only and one is write-only; both
 * accessed through CR16.  The read-only register is 32 or 64 bits wide,
 * and increments by 1 every CPU clock tick.  The architecture only
 * guarantees us a rate between 0.5 and 2, but all implementations use a
 * rate of 1.  The write-only register is 32-bits wide.  When the lowest
 * 32 bits of the read-only register compare equal to the write-only
 * register, it raises a maskable external interrupt.  Each processor has
 * an Interval Timer of its own and they are not synchronised.  
 *
 * We want to generate an interrupt every 1/HZ seconds.  So we program
 * CR16 to interrupt every @clocktick cycles.  The it_value in cpu_data
 * is programmed with the intended time of the next tick.  We can be
 * held off for an arbitrarily long period of time by interrupts being
 * disabled, so we may miss one or more ticks.
 */
58
irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id)
L
Linus Torvalds 已提交
59
{
60
	unsigned long now, now2;
61
	unsigned long next_tick;
62
	unsigned long cycles_elapsed, ticks_elapsed = 1;
63 64
	unsigned long cycles_remainder;
	unsigned int cpu = smp_processor_id();
65
	struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu);
L
Linus Torvalds 已提交
66

67
	/* gcc can optimize for "read-only" case with a local clocktick */
68
	unsigned long cpt = clocktick;
69

70
	profile_tick(CPU_PROFILING);
L
Linus Torvalds 已提交
71

72
	/* Initialize next_tick to the expected tick time. */
73
	next_tick = cpuinfo->it_value;
L
Linus Torvalds 已提交
74

75
	/* Get current cycle counter (Control Register 16). */
76
	now = mfctl(16);
L
Linus Torvalds 已提交
77

78 79
	cycles_elapsed = now - next_tick;

80
	if ((cycles_elapsed >> 6) < cpt) {
81 82
		/* use "cheap" math (add/subtract) instead
		 * of the more expensive div/mul method
83
		 */
84
		cycles_remainder = cycles_elapsed;
85 86
		while (cycles_remainder > cpt) {
			cycles_remainder -= cpt;
87
			ticks_elapsed++;
88
		}
89
	} else {
90
		/* TODO: Reduce this to one fdiv op */
91
		cycles_remainder = cycles_elapsed % cpt;
92
		ticks_elapsed += cycles_elapsed / cpt;
93 94
	}

95 96
	/* convert from "division remainder" to "remainder of clock tick" */
	cycles_remainder = cpt - cycles_remainder;
97 98 99 100 101

	/* Determine when (in CR16 cycles) next IT interrupt will fire.
	 * We want IT to fire modulo clocktick even if we miss/skip some.
	 * But those interrupts don't in fact get delivered that regularly.
	 */
102 103
	next_tick = now + cycles_remainder;

104
	cpuinfo->it_value = next_tick;
105

106 107
	/* Program the IT when to deliver the next interrupt.
	 * Only bottom 32-bits of next_tick are writable in CR16!
108
	 */
109
	mtctl(next_tick, 16);
L
Linus Torvalds 已提交
110

111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
	/* Skip one clocktick on purpose if we missed next_tick.
	 * The new CR16 must be "later" than current CR16 otherwise
	 * itimer would not fire until CR16 wrapped - e.g 4 seconds
	 * later on a 1Ghz processor. We'll account for the missed
	 * tick on the next timer interrupt.
	 *
	 * "next_tick - now" will always give the difference regardless
	 * if one or the other wrapped. If "now" is "bigger" we'll end up
	 * with a very large unsigned number.
	 */
	now2 = mfctl(16);
	if (next_tick - now2 > cpt)
		mtctl(next_tick+cpt, 16);

#if 1
/*
 * GGG: DEBUG code for how many cycles programming CR16 used.
 */
	if (unlikely(now2 - now > 0x3000)) 	/* 12K cycles */
		printk (KERN_CRIT "timer_interrupt(CPU %d): SLOW! 0x%lx cycles!"
			" cyc %lX rem %lX "
			" next/now %lX/%lX\n",
			cpu, now2 - now, cycles_elapsed, cycles_remainder,
			next_tick, now );
#endif

	/* Can we differentiate between "early CR16" (aka Scenario 1) and
	 * "long delay" (aka Scenario 3)? I don't think so.
	 *
	 * Timer_interrupt will be delivered at least a few hundred cycles
	 * after the IT fires. But it's arbitrary how much time passes
	 * before we call it "late". I've picked one second.
	 *
	 * It's important NO printk's are between reading CR16 and
	 * setting up the next value. May introduce huge variance.
	 */
	if (unlikely(ticks_elapsed > HZ)) {
		/* Scenario 3: very long delay?  bad in any case */
		printk (KERN_CRIT "timer_interrupt(CPU %d): delayed!"
			" cycles %lX rem %lX "
			" next/now %lX/%lX\n",
			cpu,
			cycles_elapsed, cycles_remainder,
			next_tick, now );
	}
156 157 158

	/* Done mucking with unreliable delivery of interrupts.
	 * Go do system house keeping.
159
	 */
160 161 162 163 164 165

	if (!--cpuinfo->prof_counter) {
		cpuinfo->prof_counter = cpuinfo->prof_multiplier;
		update_process_times(user_mode(get_irq_regs()));
	}

166 167
	if (cpu == 0)
		xtime_update(ticks_elapsed);
168

L
Linus Torvalds 已提交
169 170 171
	return IRQ_HANDLED;
}

172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189

unsigned long profile_pc(struct pt_regs *regs)
{
	unsigned long pc = instruction_pointer(regs);

	if (regs->gr[0] & PSW_N)
		pc -= 4;

#ifdef CONFIG_SMP
	if (in_lock_functions(pc))
		pc = regs->gr[2];
#endif

	return pc;
}
EXPORT_SYMBOL(profile_pc);


190
/* clock source code */
L
Linus Torvalds 已提交
191

192
static cycle_t read_cr16(struct clocksource *cs)
L
Linus Torvalds 已提交
193
{
194
	return get_cycles();
L
Linus Torvalds 已提交
195
}
196

197 198 199 200 201
static struct clocksource clocksource_cr16 = {
	.name			= "cr16",
	.rating			= 300,
	.read			= read_cr16,
	.mask			= CLOCKSOURCE_MASK(BITS_PER_LONG),
202
	.flags			= CLOCK_SOURCE_IS_CONTINUOUS,
203
};
204

205
int update_cr16_clocksource(void)
L
Linus Torvalds 已提交
206
{
207
	/* since the cr16 cycle counters are not synchronized across CPUs,
208 209
	   we'll check if we should switch to a safe clocksource: */
	if (clocksource_cr16.rating != 0 && num_online_cpus() > 1) {
210
		clocksource_change_rating(&clocksource_cr16, 0);
211
		return 1;
L
Linus Torvalds 已提交
212 213
	}

214
	return 0;
L
Linus Torvalds 已提交
215 216
}

217 218 219 220 221 222 223
void __init start_cpu_itimer(void)
{
	unsigned int cpu = smp_processor_id();
	unsigned long next_tick = mfctl(16) + clocktick;

	mtctl(next_tick, 16);		/* kick off Interval Timer (CR16) */

224
	per_cpu(cpu_data, cpu).it_value = next_tick;
225 226
}

227 228
static int __init rtc_init(void)
{
229
	struct platform_device *pdev;
230

231 232
	pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0);
	return PTR_ERR_OR_ZERO(pdev);
233
}
234
device_initcall(rtc_init);
235

236
void read_persistent_clock(struct timespec *ts)
L
Linus Torvalds 已提交
237 238
{
	static struct pdc_tod tod_data;
239 240 241 242 243 244 245 246 247 248 249 250
	if (pdc_tod_read(&tod_data) == 0) {
		ts->tv_sec = tod_data.tod_sec;
		ts->tv_nsec = tod_data.tod_usec * 1000;
	} else {
		printk(KERN_ERR "Error reading tod clock\n");
	        ts->tv_sec = 0;
		ts->tv_nsec = 0;
	}
}

void __init time_init(void)
{
251
	unsigned long current_cr16_khz;
L
Linus Torvalds 已提交
252 253 254

	clocktick = (100 * PAGE0->mem_10msec) / HZ;

255
	start_cpu_itimer();	/* get CPU 0 started */
L
Linus Torvalds 已提交
256

257 258
	/* register at clocksource framework */
	current_cr16_khz = PAGE0->mem_10msec/10;  /* kHz */
259
	clocksource_register_khz(&clocksource_cr16, current_cr16_khz);
L
Linus Torvalds 已提交
260
}
新手
引导
客服 返回
顶部