예제 #1
0
static ssize_t clocksource_read_time(struct kobj_t * kobj, void * buf, size_t size)
{
	struct clocksource_t * cs = (struct clocksource_t *)kobj->priv;
	u64_t cycle = clocksource_cycle(cs);
	u64_t time = clocksource_delta2ns(cs, cycle);
	return sprintf(buf, "%llu.%09llu", time / 1000000000ULL, time % 1000000000ULL);
}
예제 #2
0
파일: clocksource.c 프로젝트: xboot/xboot
bool_t register_clocksource(struct device_t ** device, struct clocksource_t * cs)
{
	struct device_t * dev;
	irq_flags_t flags;

	if(!cs || !cs->name || !cs->read)
		return FALSE;

	dev = malloc(sizeof(struct device_t));
	if(!dev)
		return FALSE;

	cs->keeper.interval = clocksource_deferment(cs) >> 1;
	cs->keeper.last = clocksource_cycle(cs);
	cs->keeper.nsec = 0;
	seqlock_init(&cs->keeper.lock);
	timer_init(&cs->keeper.timer, clocksource_keeper_timer_function, cs);

	dev->name = strdup(cs->name);
	dev->type = DEVICE_TYPE_CLOCKSOURCE;
	dev->driver = NULL;
	dev->priv = cs;
	dev->kobj = kobj_alloc_directory(dev->name);
	kobj_add_regular(dev->kobj, "mult", clocksource_read_mult, NULL, cs);
	kobj_add_regular(dev->kobj, "shift", clocksource_read_shift, NULL, cs);
	kobj_add_regular(dev->kobj, "period", clocksource_read_period, NULL, cs);
	kobj_add_regular(dev->kobj, "deferment", clocksource_read_deferment, NULL, cs);
	kobj_add_regular(dev->kobj, "cycle", clocksource_read_cycle, NULL, cs);
	kobj_add_regular(dev->kobj, "time", clocksource_read_time, NULL, cs);

	if(!register_device(dev))
	{
		kobj_remove_self(dev->kobj);
		free(dev->name);
		free(dev);
		return FALSE;
	}

	if(__clocksource == &__cs_dummy)
	{
		spin_lock_irqsave(&__clocksource_lock, flags);
		__clocksource = cs;
		spin_unlock_irqrestore(&__clocksource_lock, flags);
	}
	timer_start_now(&cs->keeper.timer, ns_to_ktime(cs->keeper.interval));

	if(device)
		*device = dev;
	return TRUE;
}
예제 #3
0
static int clocksource_keeper_timer_function(struct timer_t * timer, void * data)
{
	struct clocksource_t * cs = (struct clocksource_t *)(data);
	u64_t now, delta, offset;
	irq_flags_t flags;

	write_seqlock_irqsave(&cs->keeper.lock, flags);
	now = clocksource_cycle(cs);
	delta = clocksource_delta(cs, cs->keeper.last, now);
	offset = clocksource_delta2ns(cs, delta);
	cs->keeper.nsec += offset;
	cs->keeper.last = now;
	write_sequnlock_irqrestore(&cs->keeper.lock, flags);

	timer_forward_now(timer, ns_to_ktime(cs->keeper.interval));
	return 1;
}
예제 #4
0
static ssize_t clocksource_read_cycle(struct kobj_t * kobj, void * buf, size_t size)
{
	struct clocksource_t * cs = (struct clocksource_t *)kobj->priv;
	return sprintf(buf, "%llu", clocksource_cycle(cs));
}