Ejemplo n.º 1
0
Archivo: hpet.c Proyecto: sgielen/noa
void
hpet_init(void)
{
	uint64_t reg;
	uint64_t s1, s2;
	int same = 0;

	/* Disable the counter. */
	reg = hpet_read(HPET_REG_CONFIG);
	reg &= ~(HPET_LEG_RT_CNF|HPET_ENABLE_CNF);
	hpet_write(HPET_REG_CONFIG, reg);
	
	/* Reset the counter value. */
	hpet_write(HPET_REG_COUNTER, 0);

	/* Re-enable the counter. */
	reg |= HPET_ENABLE_CNF;
	hpet_write(HPET_REG_CONFIG, reg);

	/* See whether the hardware actually works. */
	s1 = hpet_read(HPET_REG_COUNTER);
	for (;;) {
		s2 = hpet_read(HPET_REG_COUNTER);
		if (s1 != s2)
			break;
		if (++same == 1000)
			panic("HPET timer missing");
	}
}
Ejemplo n.º 2
0
static int hpet_set_state_periodic(struct clock_event_device *evt)
{
	int cfg;

	spin_lock(&hpet_lock);

	pr_info("set clock event to periodic mode!\n");
	/* stop counter */
	hpet_stop_counter();

	/* enables the timer0 to generate a periodic interrupt */
	cfg = hpet_read(HPET_T0_CFG);
	cfg &= ~HPET_TN_LEVEL;
	cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL |
		HPET_TN_32BIT;
	hpet_write(HPET_T0_CFG, cfg);

	/* set the comparator */
	hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL);
	udelay(1);
	hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL);

	/* start counter */
	hpet_start_counter();

	spin_unlock(&hpet_lock);
	return 0;
}
Ejemplo n.º 3
0
static void hpet_stop_counter(void)
{
	unsigned int cfg = hpet_read(HPET_CFG);

	cfg &= ~HPET_CFG_ENABLE;
	hpet_write(HPET_CFG, cfg);
}
Ejemplo n.º 4
0
static int hpet_set_state_shutdown(struct clock_event_device *evt)
{
	int cfg;

	spin_lock(&hpet_lock);

	cfg = hpet_read(HPET_T0_CFG);
	cfg &= ~HPET_TN_ENABLE;
	hpet_write(HPET_T0_CFG, cfg);

	spin_unlock(&hpet_lock);
	return 0;
}
Ejemplo n.º 5
0
static int hpet_next_event(unsigned long delta,
		struct clock_event_device *evt)
{
	u32 cnt;
	s32 res;

	cnt = hpet_read(HPET_COUNTER);
	cnt += (u32) delta;
	hpet_write(HPET_T0_CMP, cnt);

	res = (s32)(cnt - hpet_read(HPET_COUNTER));

	return res < HPET_MIN_CYCLES ? -ETIME : 0;
}
Ejemplo n.º 6
0
static irqreturn_t hpet_irq_handler(int irq, void *data)
{
	int is_irq;
	struct clock_event_device *cd;
	unsigned int cpu = smp_processor_id();

	is_irq = hpet_read(HPET_STATUS);
	if (is_irq & HPET_T0_IRS) {
		/* clear the TIMER0 irq status register */
		hpet_write(HPET_STATUS, HPET_T0_IRS);
		cd = &per_cpu(hpet_clockevent_device, cpu);
		cd->event_handler(cd);
		return IRQ_HANDLED;
	}
	return IRQ_NONE;
}
Ejemplo n.º 7
0
static int hpet_set_state_oneshot(struct clock_event_device *evt)
{
	int cfg;

	spin_lock(&hpet_lock);

	pr_info("set clock event to one shot mode!\n");
	cfg = hpet_read(HPET_T0_CFG);
	/*
	 * set timer0 type
	 * 1 : periodic interrupt
	 * 0 : non-periodic(oneshot) interrupt
	 */
	cfg &= ~HPET_TN_PERIODIC;
	cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
	hpet_write(HPET_T0_CFG, cfg);

	spin_unlock(&hpet_lock);
	return 0;
}
Ejemplo n.º 8
0
static void hpet_reset_counter(void)
{
	hpet_write(HPET_COUNTER, 0);
	hpet_write(HPET_COUNTER + 4, 0);
}