예제 #1
0
static int s390_next_event(unsigned long delta,
			   struct clock_event_device *evt)
{
	S390_lowcore.clock_comparator = get_clock() + delta;
	set_clock_comparator(S390_lowcore.clock_comparator);
	return 0;
}
예제 #2
0
/*
 * Set up per cpu jiffy timer and set the clock comparator.
 */
static void setup_jiffy_timer(void)
{
	/* Set up clock comparator to next jiffy. */
	S390_lowcore.jiffy_timer =
		jiffies_timer_cc + (jiffies_64 + 1) * CLK_TICKS_PER_JIFFY;
	set_clock_comparator(S390_lowcore.jiffy_timer + CPU_DEVIATION);
}
예제 #3
0
/*
 * Set up lowcore and control register of the current cpu to
 * enable TOD clock and clock comparator interrupts.
 */
void init_cpu_timer(void)
{
	struct clock_event_device *cd;
	int cpu;

	S390_lowcore.clock_comparator = -1ULL;
	set_clock_comparator(S390_lowcore.clock_comparator);

	cpu = smp_processor_id();
	cd = &per_cpu(comparators, cpu);
	cd->name		= "comparator";
	cd->features		= CLOCK_EVT_FEAT_ONESHOT;
	cd->mult		= 16777;
	cd->shift		= 12;
	cd->min_delta_ns	= 1;
	cd->max_delta_ns	= LONG_MAX;
	cd->rating		= 400;
	cd->cpumask		= cpumask_of(cpu);
	cd->set_next_event	= s390_next_event;
	cd->set_mode		= s390_set_mode;

	clockevents_register_device(cd);

	/* Enable clock comparator timer interrupt. */
	__ctl_set_bit(0,11);

	/* Always allow the timing alert external interrupt. */
	__ctl_set_bit(0, 4);
}
예제 #4
0
파일: time.c 프로젝트: Adjustxx/Savaged-Zen
static void clock_comparator_interrupt(unsigned int ext_int_code,
				       unsigned int param32,
				       unsigned long param64)
{
	if (S390_lowcore.clock_comparator == -1ULL)
		set_clock_comparator(S390_lowcore.clock_comparator);
}
예제 #5
0
/*
 * Fixup the clock comparator.
 */
static void fixup_clock_comparator(unsigned long long delta)
{
	/* If nobody is waiting there's nothing to fix. */
	if (S390_lowcore.clock_comparator == -1ULL)
		return;
	S390_lowcore.clock_comparator += delta;
	set_clock_comparator(S390_lowcore.clock_comparator);
}
예제 #6
0
static void clock_comparator_interrupt(struct ext_code ext_code,
				       unsigned int param32,
				       unsigned long param64)
{
	inc_irq_stat(IRQEXT_CLK);
	if (S390_lowcore.clock_comparator == -1ULL)
		set_clock_comparator(S390_lowcore.clock_comparator);
}
예제 #7
0
static void clock_comparator_interrupt(struct ext_code ext_code,
				       unsigned int param32,
				       unsigned long param64)
{
	kstat_cpu(smp_processor_id()).irqs[EXTINT_CLK]++;
	if (S390_lowcore.clock_comparator == -1ULL)
		set_clock_comparator(S390_lowcore.clock_comparator);
}
예제 #8
0
void clock_comparator_work(void)
{
	struct clock_event_device *cd;

	S390_lowcore.clock_comparator = -1ULL;
	set_clock_comparator(S390_lowcore.clock_comparator);
	cd = &__get_cpu_var(comparators);
	cd->event_handler(cd);
}
예제 #9
0
/*
 * Start the HZ tick on the current CPU.
 * Only cpu_idle may call this function.
 */
static void start_hz_timer(void)
{
	BUG_ON(!in_interrupt());

	if (!cpu_isset(smp_processor_id(), nohz_cpu_mask))
		return;
	account_ticks(get_clock());
	set_clock_comparator(S390_lowcore.jiffy_timer + CPU_DEVIATION);
	cpu_clear(smp_processor_id(), nohz_cpu_mask);
}
예제 #10
0
static int s390_next_ktime(ktime_t expires,
			   struct clock_event_device *evt)
{
	struct timespec ts;
	u64 nsecs;

	ts.tv_sec = ts.tv_nsec = 0;
	monotonic_to_bootbased(&ts);
	nsecs = ktime_to_ns(ktime_add(timespec_to_ktime(ts), expires));
	do_div(nsecs, 125);
	S390_lowcore.clock_comparator = sched_clock_base_cc + (nsecs << 9);
	set_clock_comparator(S390_lowcore.clock_comparator);
	return 0;
}
예제 #11
0
static int s390_next_ktime(ktime_t expires,
			   struct clock_event_device *evt)
{
	struct timespec ts;
	u64 nsecs;

	ts.tv_sec = ts.tv_nsec = 0;
	monotonic_to_bootbased(&ts);
	nsecs = ktime_to_ns(ktime_add(timespec_to_ktime(ts), expires));
	do_div(nsecs, 125);
	S390_lowcore.clock_comparator = sched_clock_base_cc + (nsecs << 9);
	/* Program the maximum value if we have an overflow (== year 2042) */
	if (unlikely(S390_lowcore.clock_comparator < sched_clock_base_cc))
		S390_lowcore.clock_comparator = -1ULL;
	set_clock_comparator(S390_lowcore.clock_comparator);
	return 0;
}
예제 #12
0
/*
 * Stop the HZ tick on the current CPU.
 * Only cpu_idle may call this function.
 */
static void stop_hz_timer(void)
{
	unsigned long flags;
	unsigned long seq, next;
	__u64 timer, todval;
	int cpu = smp_processor_id();

	if (sysctl_hz_timer != 0)
		return;

	cpu_set(cpu, nohz_cpu_mask);

	/*
	 * Leave the clock comparator set up for the next timer
	 * tick if either rcu or a softirq is pending.
	 */
	if (rcu_needs_cpu(cpu) || local_softirq_pending()) {
		cpu_clear(cpu, nohz_cpu_mask);
		return;
	}

	/*
	 * This cpu is going really idle. Set up the clock comparator
	 * for the next event.
	 */
	next = next_timer_interrupt();
	do {
		seq = read_seqbegin_irqsave(&xtime_lock, flags);
		timer = ((__u64) next) - ((__u64) jiffies) + jiffies_64;
	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
	todval = -1ULL;
	/* Be careful about overflows. */
	if (timer < (-1ULL / CLK_TICKS_PER_JIFFY)) {
		timer = jiffies_timer_cc + timer * CLK_TICKS_PER_JIFFY;
		if (timer >= jiffies_timer_cc)
			todval = timer;
	}
	set_clock_comparator(todval);
}
예제 #13
0
static void clock_comparator_interrupt(__u16 code)
{
	/* set clock comparator for next tick */
	set_clock_comparator(S390_lowcore.jiffy_timer + CPU_DEVIATION);
}
예제 #14
0
static void clock_comparator_interrupt(__u16 code)
{
	if (S390_lowcore.clock_comparator == -1ULL)
		set_clock_comparator(S390_lowcore.clock_comparator);
}