--- zzzz-none-000/linux-2.6.19.2/arch/mips/kernel/process.c 2007-01-10 19:10:37.000000000 +0000 +++ davinci-8020-5505/linux-2.6.19.2/arch/mips/kernel/process.c 2007-12-18 11:38:05.000000000 +0000 @@ -45,7 +45,75 @@ #include extern void smtc_idle_loop_hook(void); #endif /* CONFIG_MIPS_MT_SMTC */ +#ifdef CONFIG_AVM_POWER +#include +#endif /*--- #ifdef CONFIG_AVM_POWER ---*/ +/*--------------------------------------------------------------------------------------*\ +\*--------------------------------------------------------------------------------------*/ +static struct _cpu_idlecount { + unsigned int last_value; + unsigned int last_value_done; + unsigned int r4k_wait_count; + unsigned int r4k_run_count; + unsigned int r4k_sum_count; + unsigned int show; +} cpu_idlecount; + +extern char *prom_getcmdline(void); + +#define COUNT_DIFF(act, last) ((act) < (last)) ? ((last) - (act)) : ((act) - (last)) +/*--------------------------------------------------------------------------------*\ +\*--------------------------------------------------------------------------------*/ +void checkidleparam(void) { + if(strstr(prom_getcmdline(), "idle")) { + cpu_idlecount.show = 1; + } +} +/*--------------------------------------------------------------------------------*\ +\*--------------------------------------------------------------------------------*/ +static void cpu_wait_start(void) { + unsigned int count, tmp; + count = get_cycles(); + if(cpu_idlecount.last_value) { + tmp = COUNT_DIFF(count, cpu_idlecount.last_value); + cpu_idlecount.r4k_run_count += tmp; + cpu_idlecount.r4k_sum_count += tmp; + } + cpu_idlecount.last_value = count; + cpu_idlecount.last_value_done = 0; +} +/*--------------------------------------------------------------------------------------*\ +\*--------------------------------------------------------------------------------------*/ +int cpu_wait_end(void) { + if(test_and_set_bit(0, &cpu_idlecount.last_value_done) == 0) { + int count, tmp; + count = get_cycles(); + tmp = COUNT_DIFF(count, cpu_idlecount.last_value); + cpu_idlecount.r4k_wait_count += tmp; + cpu_idlecount.r4k_sum_count += tmp; + cpu_idlecount.last_value = count; + return 0; + } + return 1; +} + +/*--------------------------------------------------------------------------------*\ +\*--------------------------------------------------------------------------------*/ +static int cpu_wait_info(void) { + if(cpu_idlecount.r4k_sum_count > (1 << 29)) { + int p_idle = ((cpu_idlecount.r4k_wait_count >> 8) * 100) / (cpu_idlecount.r4k_sum_count >> 8); + int p_run = ((cpu_idlecount.r4k_run_count >> 8) * 100) / (cpu_idlecount.r4k_sum_count >> 8); + + if(cpu_idlecount.show) printk("[idle]: %u%% (run %u%%)\n", p_idle, p_run); +#ifdef CONFIG_AVM_POWERMETER + PowerManagmentRessourceInfo(powerdevice_loadrate, max(0, 100 - p_idle)); +#endif/*--- #ifdef CONFIG_AVM_POWERMETER ---*/ + cpu_idlecount.r4k_sum_count >>= 8; + cpu_idlecount.r4k_wait_count >>= 8; + cpu_idlecount.r4k_run_count >>= 8; + } +} /* * The idle thread. There's no useful work to be done, so just try to conserve * power and have a low exit latency (ie sit in a loop waiting for somebody to @@ -59,9 +127,12 @@ #ifdef CONFIG_MIPS_MT_SMTC smtc_idle_loop_hook(); #endif /* CONFIG_MIPS_MT_SMTC */ + cpu_wait_start(); if (cpu_wait) (*cpu_wait)(); + cpu_wait_end(); } + cpu_wait_info(); preempt_enable_no_resched(); schedule(); preempt_disable();