/******************************************************************************
* OK335xS Linux kernel check clock 24M hacking
* 声明:
* 由于需要确认kernel中的时钟和引脚配置的时钟是否一致,于是需要去跟踪内核
* 中的代码是如何对引脚配置时钟进行识别,并对其进行相关配置的额。
*
* 2016-1-5 深圳 南山平山村 曾剑锋
*****************************************************************************/ MACHINE_START(AM335XEVM, "am335xevm")
/* Maintainer: Texas Instruments */
.atag_offset = 0x100,
.map_io = am335x_evm_map_io,
.init_early = am33xx_init_early, ---------------+
.init_irq = ti81xx_init_irq, |
.handle_irq = omap3_intc_handle_irq, |
.timer = &omap3_am33xx_timer, |
.init_machine = am335x_evm_init, |
MACHINE_END |
|
void __init am33xx_init_early(void) <--------------+
{
omap2_set_globals_am33xx();
omap3xxx_check_revision();
am33xx_check_features();
omap_common_init_early();
am33xx_voltagedomains_init();
omap44xx_prminst_init();
am33xx_powerdomains_init();
omap44xx_cminst_init();
am33xx_clockdomains_init();
am33xx_hwmod_init();
omap_hwmod_init_postsetup();
omap3xxx_clk_init(); --------------+
} |
|
int __init omap3xxx_clk_init(void) <-------------+
{
struct omap_clk *c;
u32 cpu_clkflg = ; /*
* 3505 must be tested before 3517, since 3517 returns true
* for both AM3517 chips and AM3517 family chips, which
* includes 3505. Unfortunately there's no obvious family
* test for 3517/3505 :-(
*/
if (cpu_is_omap3505()) {
cpu_mask = RATE_IN_34XX;
cpu_clkflg = CK_3505;
} else if (cpu_is_omap3517()) {
cpu_mask = RATE_IN_34XX;
cpu_clkflg = CK_3517;
} else if (cpu_is_omap3505()) {
cpu_mask = RATE_IN_34XX;
cpu_clkflg = CK_3505;
} else if (cpu_is_omap3630()) {
cpu_mask = (RATE_IN_34XX | RATE_IN_36XX);
cpu_clkflg = CK_36XX;
} else if (cpu_is_ti816x()) {
cpu_mask = RATE_IN_TI816X;
cpu_clkflg = CK_TI816X;
} else if (cpu_is_am33xx()) {
am33xx_clk_init(); ---------------------------+
return ; |
} else if (cpu_is_ti814x()) { |
cpu_mask = RATE_IN_TI814X; |
} else if (cpu_is_omap34xx()) { |
if (omap_rev() == OMAP3430_REV_ES1_0) { |
cpu_mask = RATE_IN_3430ES1; |
cpu_clkflg = CK_3430ES1; |
} else { |
/* |
* Assume that anything that we haven't matched yet |
* has 3430ES2-type clocks. |
*/ |
cpu_mask = RATE_IN_3430ES2PLUS; |
cpu_clkflg = CK_3430ES2PLUS; |
} |
} else { |
WARN(, "clock: could not identify OMAP3 variant\n"); |
} |
...... |
} |
|
int __init am33xx_clk_init(void) <-----------------------+
{
struct omap_clk *c;
u32 cpu_clkflg; if (cpu_is_am33xx()) {
cpu_mask = RATE_IN_AM33XX;
cpu_clkflg = CK_AM33XX;
} clk_init(&omap2_clk_functions); ------------------------+
|
for (c = am33xx_clks; c < am33xx_clks + ARRAY_SIZE(am33xx_clks); c++)--*---+
clk_preinit(c->lk.clk); | |
| |
for (c = am33xx_clks; c < am33xx_clks + ARRAY_SIZE(am33xx_clks); c++) | |
if (c->cpu & cpu_clkflg) { | |
clkdev_add(&c->lk); | |
clk_register(c->lk.clk); | |
omap2_init_clk_clkdm(c->lk.clk); ----------------*-+ |
} | | |
| | |
recalculate_root_clocks(); | | |
| | |
/* | | |
* Only enable those clocks we will need, let the drivers | | |
* enable other clocks as necessary | | |
*/ | | |
clk_enable_init_clocks(); -------------------------*-*-*-+
| | | |
return ; | | | |
} | | | |
| | | |
| | | |
/* Common data */ | | | |
| | | |
struct clk_functions omap2_clk_functions = { <------------------+ | | |
.clk_enable = omap2_clk_enable, | | | |
.clk_disable = omap2_clk_disable, | | | |
.clk_round_rate = omap2_clk_round_rate, | | | |
.clk_set_rate = omap2_clk_set_rate, | | | |
.clk_set_parent = omap2_clk_set_parent, | | | |
.clk_disable_unused = omap2_clk_disable_unused, | | | |
#ifdef CONFIG_CPU_FREQ | | | |
/* These will be removed when the OPP code is integrated */ | | | |
.clk_init_cpufreq_table = omap2_clk_init_cpufreq_table, | | | |
.clk_exit_cpufreq_table = omap2_clk_exit_cpufreq_table, | | | |
#endif | | | |
}; | | | |
| | | |
static struct clk_functions *arch_clock; --------------*-*-*-*-+
int __init clk_init(struct clk_functions * custom_clocks) <-------------+ | | | |
{ | | | |
if (!custom_clocks) { | | | |
pr_err("No custom clock functions registered\n"); | | | |
BUG(); | | | |
} | | | |
| | | |
arch_clock = custom_clocks; | | | |
| | | |
return ; | | | |
} | | | |
| | | |
void omap2_init_clk_clkdm(struct clk *clk) <--------------------------+ | | |
{ | | |
struct clockdomain *clkdm; | | |
| | |
if (!clk->clkdm_name) | | |
return; | | |
| | |
clkdm = clkdm_lookup(clk->clkdm_name); -------+ | | |
if (clkdm) { | | | |
printk("clock: associated clk %s to clkdm %s\n", | | | |
clk->name, clk->clkdm_name); | | | |
pr_debug("clock: associated clk %s to clkdm %s\n", | | | |
clk->name, clk->clkdm_name); | | | |
clk->clkdm = clkdm; | | | |
} else { | | | |
pr_debug("clock: could not associate clk %s to " | | | |
"clkdm %s\n", clk->name, clk->clkdm_name); | | | |
} | | | |
} | | | |
| | | |
struct clockdomain *clkdm_lookup(const char *name) <------+ | | |
{ | | |
struct clockdomain *clkdm, *temp_clkdm; | | |
| | |
if (!name) | | |
return NULL; | | |
| | |
clkdm = NULL; | | |
| | |
list_for_each_entry(temp_clkdm, &clkdm_list, node) { | | |
if (!strcmp(name, temp_clkdm->name)) { | | |
clkdm = temp_clkdm; | | |
break; | | |
} | | |
} | | |
| | |
return clkdm; | | |
} | | |
| | |
| | |
/* | | |
* clkdev +----------------------------------------------------------+ | | |
*/ | | | | |
static struct omap_clk am33xx_clks[] = { <---------------*-+ | |
...... | | |
CLK(NULL, "clk_rc32k_ck", &clk_rc32k_ck, CK_AM33XX), | | |
CLK(NULL, "virt_19_2m_ck", &virt_19_2m_ck, CK_AM33XX), | | |
CLK(NULL, "virt_24m_ck", &virt_24m_ck, CK_AM33XX), | | |
CLK(NULL, "virt_25m_ck", &virt_25m_ck, CK_AM33XX), | | |
CLK(NULL, "virt_26m_ck", &virt_26m_ck, CK_AM33XX), | | |
CLK(NULL, "sys_clkin_ck", &sys_clkin_ck, CK_AM33XX), ----+ | | |
CLK(NULL, "tclkin_ck", &tclkin_ck, CK_AM33XX), | | | |
CLK(NULL, "dpll_core_ck", &dpll_core_ck, CK_AM33XX), | | | |
CLK(NULL, "dpll_core_x2_ck", &dpll_core_x2_ck, CK_AM33XX), | | | |
CLK(NULL, "dpll_core_m4_ck", &dpll_core_m4_ck, CK_AM33XX), | | | |
CLK(NULL, "dpll_core_m5_ck", &dpll_core_m5_ck, CK_AM33XX), | | | |
CLK(NULL, "dpll_core_m6_ck", &dpll_core_m6_ck, CK_AM33XX), | | | |
CLK(NULL, "sysclk1_ck", &sysclk1_ck, CK_AM33XX), | | | |
CLK(NULL, "sysclk2_ck", &sysclk2_ck, CK_AM33XX), | | | |
...... | | | |
}; | | | | |
+-----------------------------------------+ | | | |
struct omap_clk { | <-------------*-+ | |
u16 cpu; | | | |
struct clk_lookup lk; | | | |
}; | | | |
| | | |
#define CLK(dev, con, ck, cp) \ <----+ | | |
{ \ | | |
.cpu = cp, \ | | |
.lk = { \ | | |
.dev_id = dev, \ | | |
.con_id = con, \ | | |
.clk = ck, \ | | |
}, \ | | |
} | | |
| | |
/* sys_clk_in */ | | |
static struct clk sys_clkin_ck = { <------------------+ | |
.name = "sys_clkin_ck", | |
.parent = &virt_24m_ck, | |
.init = &omap2_init_clksel_parent, ----------------------+ | |
/** | | |
* +------------------------------------------------------------------------+ | | |
* | Table 9-14. control_status Register Field Descriptions | | | |
* +-------+----------+------------+----------------------------------------+ | | |
* | Bit | Field | Type Reset | Description | | | |
* +-------+----------+------------+----------------------------------------+ | | |
* | 23-22 | sysboot1 | R/W 0h | Used to select crystal clock frequency.| | | |
* | | | | See SYSBOOT Configuration Pins. | | | |
* | | | | Reset value is from SYSBOOT[15:14]. | | | |
* +-------+----------+------------+----------------------------------------+ | | |
*/ | | |
.clksel_reg = AM33XX_CTRL_REGADDR(0x40), /* CONTROL_STATUS */ | | |
.clksel_mask = (0x3 << ), | | |
.clksel = sys_clkin_sel, -----------+ | | |
.ops = &clkops_null, -----------*-----+ | | |
.recalc = &omap2_clksel_recalc, | | | | |
}; | | | | |
| | | | |
/* Oscillator clock */ | | | | |
/* 19.2, 24, 25 or 26 MHz */ | | | | |
static const struct clksel sys_clkin_sel[] = { <----+ | | | |
{ .parent = &virt_19_2m_ck, .rates = div_1_0_rates }, | | | |
{ .parent = &virt_24m_ck, .rates = div_1_1_rates }, | ------+ | | |
{ .parent = &virt_25m_ck, .rates = div_1_2_rates }, | | | | |
{ .parent = &virt_26m_ck, .rates = div_1_3_rates }, | | | | |
{ .parent = NULL }, | | | | | |
}; | | | | | |
| | | | | |
static struct clk virt_24m_ck = { | <--------*---------+ | | |
.name = "virt_24m_ck", | | | | |
.rate = , | | | | |
.ops = &clkops_null, | | | | |
}; | | | | |
v | | | |
static const struct clksel_rate div_1_1_rates[] = { | | | |
{ .div = , .val = , .flags = RATE_IN_AM33XX }, | | | |
{ .div = }, | | | |
}; | | | |
| | | |
const struct clkops clkops_null = { <----------+ | | |
.enable = clkll_enable_null, | | |
.disable = clkll_disable_null, | | |
}; | | |
| | |
| | |
// 到目前为止都不知道哪里调用了这个函数,因为这个函数是用来判断系统接入的晶振 | | |
// 大小的,没跟踪到到底是谁调用了该函数。 | | |
void omap2_init_clksel_parent(struct clk *clk) <--------------------+ | |
{ | |
const struct clksel *clks; | |
const struct clksel_rate *clkr; | |
u32 r, found = ; | |
| |
if (!clk->clksel || !clk->clksel_mask) | |
return; | |
| |
r = __raw_readl(clk->clksel_reg) & clk->clksel_mask; | |
r >>= __ffs(clk->clksel_mask); | |
| |
for (clks = clk->clksel; clks->parent && !found; clks++) { | |
for (clkr = clks->rates; clkr->div && !found; clkr++) { | |
if (!(clkr->flags & cpu_mask)) | |
continue; | |
| |
if (clkr->val == r) { | |
if (clk->parent != clks->parent) { | |
pr_debug("clock: inited %s parent " | |
"to %s (was %s)\n", | |
clk->name, clks->parent->name, | |
((clk->parent) ? | |
clk->parent->name : "NULL")); | |
clk_reparent(clk, clks->parent); ------------+ | |
}; | | |
found = ; | | |
} | | |
} | | |
} | | |
| | |
printk("zengjf ckeck function calling [%s].\n", __func__); | | |
/* This indicates a data error */ | | |
WARN(!found, "clock: %s: init parent: could not find regval %0x\n", | | |
clk->name, r); | | |
| | |
return; | | |
} | | |
| | |
int clk_reparent(struct clk *c, struct clk *parent) <-----------+ | |
{ | |
c->parent = parent; | |
return ; | |
} | |
| |
void clk_enable_init_clocks(void) <-------------------+ |
{ |
struct clk *clkp; |
|
list_for_each_entry(clkp, &clocks, node) { |
if (clkp->flags & ENABLE_ON_INIT) |
clk_enable(clkp); -------+ |
} | |
} | |
| |
/* | |
* Standard clock functions defined in include/linux/clk.h | |
*/ | |
| |
int clk_enable(struct clk *clk) <------+ |
{ |
unsigned long flags; |
int ret; |
|
if (clk == NULL || IS_ERR(clk)) |
return -EINVAL; |
|
if (!arch_clock || !arch_clock->clk_enable) |
return -EINVAL; |
|
spin_lock_irqsave(&clockfw_lock, flags); |
ret = arch_clock->clk_enable(clk); <----------------------+
spin_unlock_irqrestore(&clockfw_lock, flags); return ret;
}
EXPORT_SYMBOL(clk_enable);

OK335xS Linux kernel check clock 24M hacking的更多相关文章

  1. linux kernel & source code analysis& hacking

    https://kernelnewbies.org/ http://www.tldp.org/LDP/lki/index.html https://kernelnewbies.org/ML https ...

  2. Linux Kernel - Debug Guide (Linux内核调试指南 )

    http://blog.csdn.net/blizmax6/article/details/6747601 linux内核调试指南 一些前言 作者前言 知识从哪里来 为什么撰写本文档 为什么需要汇编级 ...

  3. 深入linux kernel内核配置选项

    ============================================================================== 深入linux kernel内核配置选项 ...

  4. linux内核可以接受的参数 | Linux kernel启动参数 | 通过grub给内核传递参数

    在Linux中,给kernel传递参数以控制其行为总共有三种方法: 1.build kernel之时的各个configuration选项. 2.当kernel启动之时,可以参数在kernel被GRUB ...

  5. Linux kernel make 常用选项介绍

    Linux kernel 编译方法大全记录 一.这是一个我自己写的自动make脚本: #!/bin/sh export ARCH=arm export CROSS_COMPILE=arm-linux- ...

  6. karottc A Simple linux-virus Analysis、Linux Kernel <= 2.6.37 - Local Privilege Escalation、CVE-2010-4258、CVE-2010-3849、CVE-2010-3850

    catalog . 程序功能概述 . 感染文件 . 前置知识 . 获取ROOT权限: Linux Kernel <= - Local Privilege Escalation 1. 程序功能概述 ...

  7. linux kernel 字符设备详解

    有关Linux kernel 字符设备分析: 参考:http://blog.jobbole.com/86531/ 一.linux kernel 将设备分为3大类,字符设备,块设备,网络设备. 字符设备 ...

  8. arm linux kernel 从入口到start_kernel 的代码分析

    参考资料: <ARM体系结构与编程> <嵌入式Linux应用开发完全手册> Linux_Memory_Address_Mapping http://www.chinaunix. ...

  9. andriod and linux kernel启动流程

    虽然这里的Arm Linux kernel前面加上了Android,但实际上还是和普遍Arm linux kernel启动的过程一样的,这里只是结合一下Android的Makefile,讲一下boot ...

随机推荐

  1. lightoj 1408 Batting Practice (概率问题,求期望,推公式)

    题意:一个人若连续进k1个球或连续不进k2个球,游戏结束,给出这个人不进球的概率p(注意:是不进球!!!),求到游戏结束时这个投球个数的期望. 不进球概率为p,进概率 q=1-p.设 f[i] 表示连 ...

  2. POJ 2021 Relative Relatives(map+树的遍历)

    题意: 今天是Ted的100岁生日.凑巧的是,他家族里面每个人都跟他同一天生日,但是年份不同. 现在只给出一些 父亲的名字,孩子的名字,以及孩子出生时父亲的年龄, 要求将Ted以外的家族成员按年龄降序 ...

  3. ZOJ题目分类

    ZOJ题目分类初学者题: 1001 1037 1048 1049 1051 1067 1115 1151 1201 1205 1216 1240 1241 1242 1251 1292 1331 13 ...

  4. <?php $sql = <<<EOF 。。。。EOF;?>这种写法是什么意思

    php里$sql = <<<EOF //有这样的语法??????//sql语句EOF;运行mysql_query($sql)?>这是什么语法?变量声明可以这样的结构?请解答,谢 ...

  5. (转)Android之ListView原理学习与优化总结

    转自: http://jishu.zol.com.cn/12893.html 在整理前几篇文章的时候有朋友提出写一下ListView的性能优化方面的东西,这个问题也是小马在面试过程中被别人问到的….. ...

  6. linux下ssh/scp无密钥登陆方法

    一.双方机器都是root用户登陆方法 A为本地主机(即用于控制其他主机的机器) ;B为远程主机(即被控制的机器Server), 假如ip为192.168.60.110;A和B的系统都是Linux 在A ...

  7. lintcode:最小编辑距离

    最小编辑距离 给出两个单词word1和word2,计算出将word1 转换为word2的最少操作次数. 你总共三种操作方法: 插入一个字符 删除一个字符 替换一个字符 样例 给出 work1=&quo ...

  8. Android核心分析 之一分析方法论探讨之设计意图

    为什么要研究Android,是因为它够庞大,它够复杂,他激起了我作为一个程序员的内心的渴望,渴望理解这种复杂性.我研究的对象是作为手机开发平台的Android软件系统部分,而不是Dalvik虚拟机本身 ...

  9. java内存模型优化建议

    八.Java编程建议 根据GC的工作原理,我们可以通过一些技巧和方式,让GC运行更加有效率,更加符合应用程序的要求.一些关于程序设计的几点建议: 1)最基本的建议就是尽早释放无用对象的引用.大多数程序 ...

  10. QString::toWCharArray可以拷贝到宽字符串里

    wchar_t * sourcepath=new wchar_t[MAX_PATH];int s1=str.toWCharArray(sourcepath); sourcepath[s1]=0;