コード例 #1
0
ファイル: at91rm9200_time.c プロジェクト: 383530895/linux
static int
clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev)
{
	u32		alm;
	int		status = 0;

	BUG_ON(delta < 2);

	/* The alarm IRQ uses absolute time (now+delta), not the relative
	 * time (delta) in our calling convention.  Like all clockevents
	 * using such "match" hardware, we have a race to defend against.
	 *
	 * Our defense here is to have set up the clockevent device so the
	 * delta is at least two.  That way we never end up writing RTAR
	 * with the value then held in CRTR ... which would mean the match
	 * wouldn't trigger until 32 seconds later, after CRTR wraps.
	 */
	alm = read_CRTR();

	/* Cancel any pending alarm; flush any pending IRQ */
	at91_st_write(AT91_ST_RTAR, alm);
	at91_st_read(AT91_ST_SR);

	/* Schedule alarm by writing RTAR. */
	alm += delta;
	at91_st_write(AT91_ST_RTAR, alm);

	return status;
}
コード例 #2
0
static void
clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev)
{
	
	at91_st_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS);
	at91_st_read(AT91_ST_SR);

	last_crtr = read_CRTR();
	switch (mode) {
	case CLOCK_EVT_MODE_PERIODIC:
		
		irqmask = AT91_ST_PITS;
		at91_st_write(AT91_ST_PIMR, RM9200_TIMER_LATCH);
		break;
	case CLOCK_EVT_MODE_ONESHOT:
		irqmask = AT91_ST_ALMS;
		at91_st_write(AT91_ST_RTAR, last_crtr);
		break;
	case CLOCK_EVT_MODE_SHUTDOWN:
	case CLOCK_EVT_MODE_UNUSED:
	case CLOCK_EVT_MODE_RESUME:
		irqmask = 0;
		break;
	}
	at91_st_write(AT91_ST_IER, irqmask);
}
コード例 #3
0
static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id)
{
	u32	sr = at91_st_read(AT91_ST_SR) & irqmask;

	WARN_ON_ONCE(!irqs_disabled());

	
	if (sr & AT91_ST_ALMS) {
		clkevt.event_handler(&clkevt);
		return IRQ_HANDLED;
	}

	
	if (sr & AT91_ST_PITS) {
		u32	crtr = read_CRTR();

		while (((crtr - last_crtr) & AT91_ST_CRTV) >= RM9200_TIMER_LATCH) {
			last_crtr += RM9200_TIMER_LATCH;
			clkevt.event_handler(&clkevt);
		}
		return IRQ_HANDLED;
	}

	
	return IRQ_NONE;
}
コード例 #4
0
ファイル: at91rm9200_time.c プロジェクト: 383530895/linux
/*
 * IRQ handler for the timer.
 */
static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id)
{
	u32	sr = at91_st_read(AT91_ST_SR) & irqmask;

	/*
	 * irqs should be disabled here, but as the irq is shared they are only
	 * guaranteed to be off if the timer irq is registered first.
	 */
	WARN_ON_ONCE(!irqs_disabled());

	/* simulate "oneshot" timer with alarm */
	if (sr & AT91_ST_ALMS) {
		clkevt.event_handler(&clkevt);
		return IRQ_HANDLED;
	}

	/* periodic mode should handle delayed ticks */
	if (sr & AT91_ST_PITS) {
		u32	crtr = read_CRTR();

		while (((crtr - last_crtr) & AT91_ST_CRTV) >= RM9200_TIMER_LATCH) {
			last_crtr += RM9200_TIMER_LATCH;
			clkevt.event_handler(&clkevt);
		}
		return IRQ_HANDLED;
	}

	/* this irq is shared ... */
	return IRQ_NONE;
}
コード例 #5
0
ファイル: at91rm9200_time.c プロジェクト: 383530895/linux
static void
clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev)
{
	/* Disable and flush pending timer interrupts */
	at91_st_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS);
	at91_st_read(AT91_ST_SR);

	last_crtr = read_CRTR();
	switch (mode) {
	case CLOCK_EVT_MODE_PERIODIC:
		/* PIT for periodic irqs; fixed rate of 1/HZ */
		irqmask = AT91_ST_PITS;
		at91_st_write(AT91_ST_PIMR, RM9200_TIMER_LATCH);
		break;
	case CLOCK_EVT_MODE_ONESHOT:
		/* ALM for oneshot irqs, set by next_event()
		 * before 32 seconds have passed
		 */
		irqmask = AT91_ST_ALMS;
		at91_st_write(AT91_ST_RTAR, last_crtr);
		break;
	case CLOCK_EVT_MODE_SHUTDOWN:
	case CLOCK_EVT_MODE_UNUSED:
	case CLOCK_EVT_MODE_RESUME:
		irqmask = 0;
		break;
	}
	at91_st_write(AT91_ST_IER, irqmask);
}
コード例 #6
0
static void
clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev)
{
	unsigned int val;

	/* Disable and flush pending timer interrupts */
	regmap_write(regmap_st, AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS);
	regmap_read(regmap_st, AT91_ST_SR, &val);

	last_crtr = read_CRTR();
	switch (mode) {
	case CLOCK_EVT_MODE_PERIODIC:
		/* PIT for periodic irqs; fixed rate of 1/HZ */
		irqmask = AT91_ST_PITS;
		regmap_write(regmap_st, AT91_ST_PIMR, RM9200_TIMER_LATCH);
		break;
	case CLOCK_EVT_MODE_ONESHOT:
		/* ALM for oneshot irqs, set by next_event()
		 * before 32 seconds have passed
		 */
		irqmask = AT91_ST_ALMS;
		regmap_write(regmap_st, AT91_ST_RTAR, last_crtr);
		break;
	case CLOCK_EVT_MODE_SHUTDOWN:
	case CLOCK_EVT_MODE_UNUSED:
		remove_irq(NR_IRQS_LEGACY + AT91_ID_SYS, &at91rm9200_timer_irq);
	case CLOCK_EVT_MODE_RESUME:
		irqmask = 0;
		break;
	}
	regmap_write(regmap_st, AT91_ST_IER, irqmask);
}
コード例 #7
0
ファイル: time.c プロジェクト: waterzhou/Handheld4Tagmaster
/*
 * Returns number of microseconds since last timer interrupt.  Note that interrupts
 * will have been disabled by do_gettimeofday()
 *  'LATCH' is hwclock ticks (see CLOCK_TICK_RATE in timex.h) per jiffy.
 *  'tick' is usecs per jiffy (linux/timex.h).
 */
static unsigned long at91rm9200_gettimeoffset(void)
{
	unsigned long elapsed;

	elapsed = (read_CRTR() - last_crtr) & AT91_ST_ALMV;

	return (unsigned long)(elapsed * (tick_nsec / 1000)) / LATCH;
}
コード例 #8
0
ファイル: timer-atmel-st.c プロジェクト: ChineseDr/linux
static void clkdev32k_disable_and_flush_irq(void)
{
    unsigned int val;

    /* Disable and flush pending timer interrupts */
    regmap_write(regmap_st, AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS);
    regmap_read(regmap_st, AT91_ST_SR, &val);
    last_crtr = read_CRTR();
}
コード例 #9
0
ファイル: time.c プロジェクト: waterzhou/Handheld4Tagmaster
/*
 * IRQ handler for the timer.
 */
static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
	if (at91_sys_read(AT91_ST_SR) & AT91_ST_PITS) {	/* This is a shared interrupt */
		write_seqlock(&xtime_lock);

		while (((read_CRTR() - last_crtr) & AT91_ST_ALMV) >= LATCH) {
			timer_tick(regs);
			last_crtr = (last_crtr + LATCH) & AT91_ST_ALMV;
		}

		write_sequnlock(&xtime_lock);

		return IRQ_HANDLED;
	}
	else
		return IRQ_NONE;		/* not handled */
}
コード例 #10
0
static int
clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev)
{
	u32		alm;
	int		status = 0;

	BUG_ON(delta < 2);

	alm = read_CRTR();

	
	at91_st_write(AT91_ST_RTAR, alm);
	at91_st_read(AT91_ST_SR);

	
	alm += delta;
	at91_st_write(AT91_ST_RTAR, alm);

	return status;
}
コード例 #11
0
static cycle_t read_clk32k(struct clocksource *cs)
{
	return read_CRTR();
}