@ -23,6 +23,7 @@
# include <hwregs/timer_defs.h>
# include <asm/fasttimer.h>
# include <linux/proc_fs.h>
# include <linux/seq_file.h>
/*
* timer0 is running at 100 MHz and generating jiffies timer ticks
@ -463,194 +464,161 @@ void schedule_usleep(unsigned long us)
}
# ifdef CONFIG_PROC_FS
static int proc_fasttimer_read ( char * buf , char * * start , off_t offset , int len
, int * eof , void * data_unused ) ;
# endif /* CONFIG_PROC_FS */
# ifdef CONFIG_PROC_FS
/* This value is very much based on testing */
# define BIG_BUF_SIZE (500 + NUM_TIMER_STATS * 300)
static int proc_fasttimer_read ( char * buf , char * * start , off_t offset , int len
, int * eof , void * data_unused )
static int proc_fasttimer_show ( struct seq_file * m , void * v )
{
unsigned long flags ;
int i = 0 ;
int num_to_show ;
unsigned long flags ;
int i = 0 ;
int num_to_show ;
struct fasttime_t tv ;
struct fast_timer * t , * nextt ;
static char * bigbuf = NULL ;
static unsigned long used ;
if ( ! bigbuf ) {
bigbuf = vmalloc ( BIG_BUF_SIZE ) ;
if ( ! bigbuf ) {
used = 0 ;
if ( buf )
buf [ 0 ] = ' \0 ' ;
return 0 ;
}
}
if ( ! offset | | ! used ) {
do_gettimeofday_fast ( & tv ) ;
used = 0 ;
used + = sprintf ( bigbuf + used , " Fast timers added: %i \n " ,
fast_timers_added ) ;
used + = sprintf ( bigbuf + used , " Fast timers started: %i \n " ,
fast_timers_started ) ;
used + = sprintf ( bigbuf + used , " Fast timer interrupts: %i \n " ,
fast_timer_ints ) ;
used + = sprintf ( bigbuf + used , " Fast timers expired: %i \n " ,
fast_timers_expired ) ;
used + = sprintf ( bigbuf + used , " Fast timers deleted: %i \n " ,
fast_timers_deleted ) ;
used + = sprintf ( bigbuf + used , " Fast timer running: %s \n " ,
fast_timer_running ? " yes " : " no " ) ;
used + = sprintf ( bigbuf + used , " Current time: %lu.%06lu \n " ,
( unsigned long ) tv . tv_jiff ,
( unsigned long ) tv . tv_usec ) ;
struct fast_timer * t , * nextt ;
do_gettimeofday_fast ( & tv ) ;
seq_printf ( m , " Fast timers added: %i \n " , fast_timers_added ) ;
seq_printf ( m , " Fast timers started: %i \n " , fast_timers_started ) ;
seq_printf ( m , " Fast timer interrupts: %i \n " , fast_timer_ints ) ;
seq_printf ( m , " Fast timers expired: %i \n " , fast_timers_expired ) ;
seq_printf ( m , " Fast timers deleted: %i \n " , fast_timers_deleted ) ;
seq_printf ( m , " Fast timer running: %s \n " ,
fast_timer_running ? " yes " : " no " ) ;
seq_printf ( m , " Current time: %lu.%06lu \n " ,
( unsigned long ) tv . tv_jiff ,
( unsigned long ) tv . tv_usec ) ;
# ifdef FAST_TIMER_SANITY_CHECKS
used + = sprintf ( bigbuf + used , " Sanity failed: %i \n " ,
sanity_failed ) ;
seq_printf ( m , " Sanity failed: %i \n " , sanity_failed ) ;
# endif
used + = sprintf ( bigbuf + used , " \n " ) ;
seq_putc ( m , ' \n ' ) ;
# ifdef DEBUG_LOG_INCLUDED
{
int end_i = debug_log_cnt ;
i = 0 ;
if ( debug_log_cnt_wrapped )
i = debug_log_cnt ;
while ( ( i ! = end_i | | ( debug_log_cnt_wrapped & & ! used ) ) & &
used + 100 < BIG_BUF_SIZE )
{
used + = sprintf ( bigbuf + used , debug_log_string [ i ] ,
debug_log_value [ i ] ) ;
i = ( i + 1 ) % DEBUG_LOG_MAX ;
}
}
used + = sprintf ( bigbuf + used , " \n " ) ;
{
int end_i = debug_log_cnt ;
i = 0 ;
if ( debug_log_cnt_wrapped )
i = debug_log_cnt ;
while ( ( i ! = end_i | | debug_log_cnt_wrapped ) ) {
if ( seq_printf ( m , debug_log_string [ i ] , debug_log_value [ i ] ) < 0 )
return 0 ;
i = ( i + 1 ) % DEBUG_LOG_MAX ;
}
}
seq_putc ( m , ' \n ' ) ;
# endif
num_to_show = ( fast_timers_started < NUM_TIMER_STATS ? fast_timers_started :
NUM_TIMER_STATS ) ;
used + = sprintf ( bigbuf + used , " Timers started: %i \n " , fast_timers_started ) ;
for ( i = 0 ; i < num_to_show & & ( used + 100 < BIG_BUF_SIZE ) ; i + + )
{
int cur = ( fast_timers_started - i - 1 ) % NUM_TIMER_STATS ;
num_to_show = ( fast_timers_started < NUM_TIMER_STATS ? fast_timers_started :
NUM_TIMER_STATS ) ;
seq_printf ( m , " Timers started: %i \n " , fast_timers_started ) ;
for ( i = 0 ; i < num_to_show ; i + + ) {
int cur = ( fast_timers_started - i - 1 ) % NUM_TIMER_STATS ;
# if 1 //ndef FAST_TIMER_LOG
used + = sprintf ( bigbuf + used , " div: %i delay: %i "
" \n " ,
timer_div_settings [ cur ] ,
timer_delay_settings [ cur ]
) ;
seq_printf ( m , " div: %i delay: %i "
" \n " ,
timer_div_settings [ cur ] ,
timer_delay_settings [ cur ] ) ;
# endif
# ifdef FAST_TIMER_LOG
t = & timer_started_log [ cur ] ;
used + = sprintf ( bigbuf + used , " %-14s s: %6lu.%06lu e: %6lu.%06lu "
" d: %6li us data: 0x%08lX "
" \n " ,
t - > name ,
( unsigned long ) t - > tv_set . tv_jiff ,
( unsigned long ) t - > tv_set . tv_usec ,
( unsigned long ) t - > tv_expires . tv_jiff ,
( unsigned long ) t - > tv_expires . tv_usec ,
t - > delay_us ,
t - > data
) ;
t = & timer_started_log [ cur ] ;
if ( seq_printf ( m , " %-14s s: %6lu.%06lu e: %6lu.%06lu "
" d: %6li us data: 0x%08lX "
" \n " ,
t - > name ,
( unsigned long ) t - > tv_set . tv_jiff ,
( unsigned long ) t - > tv_set . tv_usec ,
( unsigned long ) t - > tv_expires . tv_jiff ,
( unsigned long ) t - > tv_expires . tv_usec ,
t - > delay_us ,
t - > data ) < 0 )
return 0 ;
# endif
}
used + = sprintf ( bigbuf + used , " \n " ) ;
}
seq_putc ( m , ' \n ' ) ;
# ifdef FAST_TIMER_LOG
num_to_show = ( fast_timers_added < NUM_TIMER_STATS ? fast_timers_added :
NUM_TIMER_STATS ) ;
used + = sprintf ( bigbuf + used , " Timers added: %i \n " , fast_timers_added ) ;
for ( i = 0 ; i < num_to_show & & ( used + 100 < BIG_BUF_SIZE ) ; i + + )
{
t = & timer_added_log [ ( fast_timers_added - i - 1 ) % NUM_TIMER_STATS ] ;
used + = sprintf ( bigbuf + used , " %-14s s: %6lu.%06lu e: %6lu.%06lu "
" d: %6li us data: 0x%08lX "
" \n " ,
t - > name ,
( unsigned long ) t - > tv_set . tv_jiff ,
( unsigned long ) t - > tv_set . tv_usec ,
( unsigned long ) t - > tv_expires . tv_jiff ,
( unsigned long ) t - > tv_expires . tv_usec ,
t - > delay_us ,
t - > data
) ;
}
used + = sprintf ( bigbuf + used , " \n " ) ;
num_to_show = ( fast_timers_expired < NUM_TIMER_STATS ? fast_timers_expired :
NUM_TIMER_STATS ) ;
used + = sprintf ( bigbuf + used , " Timers expired: %i \n " , fast_timers_expired ) ;
for ( i = 0 ; i < num_to_show & & ( used + 100 < BIG_BUF_SIZE ) ; i + + )
{
t = & timer_expired_log [ ( fast_timers_expired - i - 1 ) % NUM_TIMER_STATS ] ;
used + = sprintf ( bigbuf + used , " %-14s s: %6lu.%06lu e: %6lu.%06lu "
" d: %6li us data: 0x%08lX "
" \n " ,
t - > name ,
( unsigned long ) t - > tv_set . tv_jiff ,
( unsigned long ) t - > tv_set . tv_usec ,
( unsigned long ) t - > tv_expires . tv_jiff ,
( unsigned long ) t - > tv_expires . tv_usec ,
t - > delay_us ,
t - > data
) ;
}
used + = sprintf ( bigbuf + used , " \n " ) ;
num_to_show = ( fast_timers_added < NUM_TIMER_STATS ? fast_timers_added :
NUM_TIMER_STATS ) ;
seq_printf ( m , " Timers added: %i \n " , fast_timers_added ) ;
for ( i = 0 ; i < num_to_show ; i + + ) {
t = & timer_added_log [ ( fast_timers_added - i - 1 ) % NUM_TIMER_STATS ] ;
if ( seq_printf ( m , " %-14s s: %6lu.%06lu e: %6lu.%06lu "
" d: %6li us data: 0x%08lX "
" \n " ,
t - > name ,
( unsigned long ) t - > tv_set . tv_jiff ,
( unsigned long ) t - > tv_set . tv_usec ,
( unsigned long ) t - > tv_expires . tv_jiff ,
( unsigned long ) t - > tv_expires . tv_usec ,
t - > delay_us ,
t - > data ) < 0 )
return 0 ;
}
seq_putc ( m , ' \n ' ) ;
num_to_show = ( fast_timers_expired < NUM_TIMER_STATS ? fast_timers_expired :
NUM_TIMER_STATS ) ;
seq_printf ( m , " Timers expired: %i \n " , fast_timers_expired ) ;
for ( i = 0 ; i < num_to_show ; i + + ) {
t = & timer_expired_log [ ( fast_timers_expired - i - 1 ) % NUM_TIMER_STATS ] ;
if ( seq_printf ( m , " %-14s s: %6lu.%06lu e: %6lu.%06lu "
" d: %6li us data: 0x%08lX "
" \n " ,
t - > name ,
( unsigned long ) t - > tv_set . tv_jiff ,
( unsigned long ) t - > tv_set . tv_usec ,
( unsigned long ) t - > tv_expires . tv_jiff ,
( unsigned long ) t - > tv_expires . tv_usec ,
t - > delay_us ,
t - > data ) < 0 )
return 0 ;
}
seq_putc ( m , ' \n ' ) ;
# endif
used + = sprintf ( bigbuf + used , " Active timers: \n " ) ;
local_irq_save ( flags ) ;
t = fast_timer_list ;
while ( t ! = NULL & & ( used + 100 < BIG_BUF_SIZE ) )
{
nextt = t - > next ;
local_irq_restore ( flags ) ;
used + = sprintf ( bigbuf + used , " %-14s s: %6lu.%06lu e: %6lu.%06lu "
" d: %6li us data: 0x%08lX "
seq_puts ( m , " Active timers: \n " ) ;
local_irq_save ( flags ) ;
t = fast_timer_list ;
while ( t ! = NULL ) {
nextt = t - > next ;
local_irq_restore ( flags ) ;
if ( seq_printf ( m , " %-14s s: %6lu.%06lu e: %6lu.%06lu "
" d: %6li us data: 0x%08lX "
/* " func: 0x%08lX" */
" \n " ,
t - > name ,
( unsigned long ) t - > tv_set . tv_jiff ,
( unsigned long ) t - > tv_set . tv_usec ,
( unsigned long ) t - > tv_expires . tv_jiff ,
( unsigned long ) t - > tv_expires . tv_usec ,
t - > delay_us ,
t - > data
" \n " ,
t - > name ,
( unsigned long ) t - > tv_set . tv_jiff ,
( unsigned long ) t - > tv_set . tv_usec ,
( unsigned long ) t - > tv_expires . tv_jiff ,
( unsigned long ) t - > tv_expires . tv_usec ,
t - > delay_us ,
t - > data
/* , t->function */
) ;
local_irq_save ( flags ) ;
if ( t - > next ! = nextt )
{
printk ( " timer removed! \n " ) ;
}
t = nextt ;
}
local_irq_restore ( flags ) ;
}
) < 0 )
return 0 ;
local_irq_save ( flags ) ;
if ( t - > next ! = nextt )
printk ( " timer removed! \n " ) ;
t = nextt ;
}
local_irq_restore ( flags ) ;
return 0 ;
}
if ( used - offset < len )
{
len = used - offset ;
}
static int proc_fasttimer_open ( struct inode * inode , struct file * file )
{
return single_open_size ( file , proc_fasttimer_show , PDE_DATA ( inode ) , BIG_BUF_SIZE ) ;
}
memcpy ( buf , bigbuf + offset , len ) ;
* start = buf ;
* eof = 1 ;
static const struct file_operations proc_fasttimer_fops = {
. open = proc_fasttimer_open ,
. read = seq_read ,
. llseek = seq_lseek ,
. release = seq_release ,
} ;
return len ;
}
# endif /* PROC_FS */
# ifdef FAST_TIMER_TEST
@ -815,7 +783,7 @@ int fast_timer_init(void)
printk ( " fast_timer_init() \n " ) ;
# ifdef CONFIG_PROC_FS
create_proc_read_entry ( " fasttimer " , 0 , NULL , proc_fasttimer_read , NULL ) ;
proc_create ( " fasttimer " , 0 , NULL , & proc_fasttimer_fops ) ;
# endif /* PROC_FS */
if ( request_irq ( TIMER0_INTR_VECT , timer_trig_interrupt ,
IRQF_SHARED | IRQF_DISABLED ,