/dev/watchdog
/sys/bus/platform/devices/zx29_ap_wdt.0
/sys/bus/platform/drivers/zx29_ap_wdt
| arch/arm/mach-zx297520v3/include/mach/iomap.h #define ZX_LSP_CRPM_BASE (ZX_LSP_BASE) drivers/clk/zte/clk-zx297520v3.c /************************************************************************** static struct zx29_hwclk ap_wdt_apb =  static struct zx29_hwclk ap_wdt_work =  
 struct clk_lookup periph_clocks_lookups[] = { }; | 
中:
| arch/arm/mach-zx297520v3/include/mach/iomap.h #define ZX_AP_WDT_BASE (ZX_LSP_BASE + 0xE000) arch/arm/mach-zx297520v3/zx297520v3-devices.c (这其中的资源会在probe中使用到) static struct resource wdt_res[] = { static struct platform_device zx297520v2_wdt_device = { struct platform_device *zx29_device_table[] __initdata={ … | 
drivers/watchdog/zx29_wdt.c中:
时钟相关
| watchdog_init->platform_driver_register(&zx29_wdt_driver)-|->zx29_wdt_probe -|->__devexit_p(zx29_wdt_remove) -|->zx29_wdt_shutdown -|->zx29_wdt_suspend -|->zx29_wdt_resume watchdog_exit->platform_driver_unregister(&zx29_wdt_driver) | 
menuconfig
| CONFIG_CPU_IDLE=y | 
在本平台中cpuidle driver没有作为单一的模块,二是放在zx_pm_init中进行。
drivers/soc/zte/power/zx-cpuidle.c
| zx_pm_init-|->pm_debug_init->idle_debug_init (/sys/zte_pm/cpuidle/) |->zx_cpuidle_init-> | 
drivers/soc/zte/power/zx297520v3-cpuidle.c中定义了cpuidle的状态
| #define WHOLE_CHIP_EXIT_LATENCY (4000) /* us */ #define LP2_DEFAULT_EXIT_LATENCY    (500 + WHOLE_CHIP_EXIT_LATENCY)         /* us */ #define LP2_DELTA_EXIT_LATENCY (100) /* us -- for timer setting refresh time, should > 2us. 
 static struct cpuidle_state zx297520v3_cpuidle_set[] __initdata = | 
cpu_idle在start_kernel->rest_init->cpu_idle->while(1)中调用。cpu_idle调用cpuidle_idle_call:
| cpu_idle->cpuidle_idle_call-|->trace_cpu_idle_rcuidle(next_state, dev->cpu); |->trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu); | 
| cpuidle_curr_governor->select(drv, dev) 根据当前的governor,选择合适的cpuidle状态 entered_state = cpuidle_enter_state(dev, drv, next_state); cpuidle_curr_governor->reflect(dev, entered_state) | 
cpuidle_curr_governor在cpuidle_switch_governor中进行设置,一个是在cpuidle_register_governor注册时的时候,另一个是在store_current_governor通过sysfs节点设置cpuidle governor的时候。由于默认使用的是menu_governor,下面就来重点分析一下:
static struct cpuidle_governor menu_governor = {
	.name =		"menu",
	.rating =	20,
	.enable =	menu_enable_device,
	.select =	menu_select,
	.reflect =	menu_reflect,
	.owner =	THIS_MODULE,
};
》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
cpuidle_enter_state是执行根据governor确定的状态执行,然后返回进入的状态值。
cpuidle_enable_device设置cpuidle_enter_ops的值,cpuidle_enter_ops = drv->en_core_tk_irqen?cpuidle_enter_tk:cpuidle_enter;
cpuidle_enter调用target_state->enter(dev, drv, index);,指向zx_enter_idle。
| zx_enter_idle-|->zx_pm_idle_prepare | 
drivers/soc/zte/power/zx-cpufreq.c
drvers/soc/zte/power/zx297520v3-cpufreq.c
设置cpufreq的DVFS数据,在struct zx_dvfs_info中。
| struct zx_dvfs_info { | 
cpufreq driver想初始化DVFS通过调用zx29xx_cpufreq_init。
| static int zx297520v3_cpufreq_init(struct zx_dvfs_info *info)     cpu_clk = clk_get(NULL, "cpu_clk");     info->freq_cur_idx         = L1; cpufreq_driver_inited = 1;     INIT_DELAYED_WORK_DEFERRABLE(&pm_freq_work, pm_freq_func); 
     return 0; | 
cpu_clk如下:
| static struct zx29_hwclk cpu_work = { CLK_ZX29_CONFIG(NULL, "cpu_clk", &cpu_work_clk), | 
这里通过zx297520v3_volt_table和zx297520v3_freq_table来达到OPP的概念,zx297520v3_set_frequency作为设置频率的底层函数。
| static unsigned int zx297520v3_volt_table[CPUFREQ_LEVEL_END] = { static struct cpufreq_frequency_table zx297520v3_freq_table[] = { 实际的频率只有两种,而且不可以调压 | 
由于是单核CPU,所以不能使用hotplug功能。
kernel/power/main.c
| #ifdef CONFIG_PM_WAKELOCKS static ssize_t wake_lock_store(struct kobject *kobj, power_attr(wake_lock); static ssize_t wake_unlock_show(struct kobject *kobj, static ssize_t wake_unlock_store(struct kobject *kobj, power_attr(wake_unlock); #endif /* CONFIG_PM_WAKELOCKS */ 
 static struct attribute * g[] = { | 
kernel/power/wakelock.c
修改config.linux:
| CONFIG_PM_DEBUG=y
CONFIG_PM_SLEEP_DEBUG=y
CONFIG_FTRACE=y
CONFIG_FUNCTION_TRACER=y
CONFIG_FUNCTION_GRAPH_TRACER=y
CONFIG_KPROBES=y
CONFIG_KPROBES_ON_FTRACE=y | 
修改include/trace/events/power.h,增加wakelock相关trace包括pm_wake_lock和pm_wake_unlock。
修改kernel/power/wakelock.c,在pm_wake_lock和pm_wake_unlock中添加trace。
| Index: wakelock.c | 
原文:http://www.cnblogs.com/arnoldlu/p/6894158.html