hrtime.c
来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 162 行
C
162 行
/* * linux/arch/arm/mach-omap2/hrtime.c * * High-Res Timer Implementation for OMAP2 * HRT port on 24xx uses Timer4 to receive notification after elapsed time * * Copyright (C) 2004 Texas Instruments, Inc. * * This package is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */#include <linux/config.h>#include <linux/init.h>#include <linux/sched.h>#include <linux/time.h>#include <linux/hrtime.h>#include <linux/timex.h>#include <linux/kernel.h>#include <linux/interrupt.h>#include <asm/errno.h>#include <asm/hardware.h>#include <asm/mach/irq.h>#include <asm/irq.h>int hrtimer_use = 0;typedef struct { u32 tidr; /*timer identification */ u32 filer1; /*reserved */ u32 filer2; /*reserved */ u32 filer3; /*reserved */ u32 ti_ocpcfg; /*ocp configuration */ u32 tistat; /*interrupt status */ u32 tisr; /*Timer status */ u32 tier; /*Timer interrupt enable */ u32 twer; /*Timer wake-up enable */ u32 tclr; /*Timer control */ u32 tcrr; /*Timer counter */ u32 tldr; /*Timer load */ u32 ttgr; /*Timer trigger */ u32 twps; /*Timer write posted status */ u32 tmar; /*Timer match */ u32 tcar; /*Timer capture */ u32 tsicr; /*Timer synchronization interface control */} mputimer_regs_t;#define HRT_TIMER_BASE IO_ADDRESS(OMAP24XX_TIMER4_BASE)#define HRT_TIMER_IRQ INT_GPT4_IRQ/*Program HRT Timer to generate interrupt at (ref_jiffies * *arch_cycles_per_jiffy)+ref_cycles clock cycles from current time *this is called by __run_timers.this means that some Kernel Timer in Kernel *Timer List will expire at (ref_jiffies * arch_cycles_per_jiffy) * +ref_cycles from current time */int schedule_hr_timer_int(unsigned ref_jiffies, int ref_cycles){ int temp_cycles; volatile mputimer_regs_t *subhz_timer = (mputimer_regs_t *) HRT_TIMER_BASE; BUG_ON(ref_cycles < 0); /*calculate the time(in terms of clock cycles) the time interval from now to the time specified by ref_jiffies+ref_cycles after ref_jiffies */ temp_cycles = (ref_jiffies - jiffies) * arch_cycles_per_jiffy + ref_cycles - get_arch_cycles(jiffies); if (unlikely(temp_cycles <= 0)) return -ETIME; /*posted mode active */ subhz_timer->tsicr = 0x0; subhz_timer->tcrr = 0xffffffff - (temp_cycles - 1); /*enable overflow interrupt */ subhz_timer->tier = (0x1 << 1); /*prescalar enable,start timer */ subhz_timer->tclr = ((0x1 << 5) | (0x1 << 0)); return 0;}/*get the elapsed timer(in terms of clock cycles) from ref_jiffies*/int get_arch_cycles(unsigned ref_jiffies){ extern unsigned long systimer_mark; extern unsigned long do_getmachinecycles(void); int ret; unsigned temp_jiffies; unsigned diff_jiffies; do { /* snapshot jiffies */ temp_jiffies = jiffies; /*ensures that the opeartors placed before this are finished *before starting operations placed after this */ barrier(); /* calculate cycles since the current jiffy */ ret = do_getmachinecycles() - systimer_mark; /* compensate for ref_jiffies in the past */ if (unlikely(diff_jiffies = jiffies - ref_jiffies)) ret += diff_jiffies * arch_cycles_per_jiffy; barrier(); /* repeat if we didn't have a consistent view of the world */ } while (unlikely(temp_jiffies != jiffies)); return ret;}/*interrupt handler for HRT Timer*/static irqreturn_t hr_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs){ volatile mputimer_regs_t *subhz_timer = (mputimer_regs_t *) HRT_TIMER_BASE; /*clear timer interrupt status register */ subhz_timer->tisr = subhz_timer->tisr; /*stop timer */ subhz_timer->tclr = 0; /*some Kernel Timer would have expired this time *so process the timer list *do_hr_timer_int define as run_local_timers in include/linux/hrtime.h *run_local_timers in turn calls __run_timers which process timer list */ do_hr_timer_int(); return IRQ_HANDLED;}static struct irqaction hr_timer_irq = { .name = "high-res timer", .handler = hr_timer_interrupt, .flags = SA_INTERRUPT};static int hr_timer_init(void){ int ret; volatile mputimer_regs_t *subhz_timer = (mputimer_regs_t *) HRT_TIMER_BASE; subhz_timer->tclr = 0; ret = setup_irq(HRT_TIMER_IRQ, &hr_timer_irq); hrtimer_use = 1; return ret;}__initcall(hr_timer_init);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?