/******************************************************************************
* 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. 浅谈javascript中的数据类型和引用类型

    1.概述 javascript中有五种简单数据类型和一种复杂数据类型. 分别是:undefind, null, number, string ,boolean ----简单数据类型          ...

  2. appium获取android app的包名和主Activity

    方法一在appium的android setting中选择下载到电脑上的app包,获取Activity. 方法二在android-sdk中安装build-tools包,进入这个目录.aapt dump ...

  3. cf 403 D

    D. Beautiful Pairs of Numbers time limit per test 3 seconds memory limit per test 256 megabytes inpu ...

  4. D&F学数据结构系列——B树(B-树和B+树)介绍

    B树 定义:一棵B树T是具有如下性质的有根树: 1)每个节点X有以下域: a)n[x],当前存储在X节点中的关键字数, b)n[x]个关键字本身,以非降序存放,因此key1[x]<=key2[x ...

  5. EF框架 完整项目记录

    今天终于能用EF框架搭建一个项目,同时能连接sqlserver 数据库.mysql 数据库 1.必须的文件 2.将必须文件导入项目,此处用到“管理 NuGet 程序包”,由于从网上下载比较慢,此处从本 ...

  6. (6)妈的终于找到能用的nehe sdk了

    在网上下载了有十多个,终于找到一个能用的了 下面是下载地址: http://download.csdn.net/detail/jason_bourn/681620#comment 泪奔啊~

  7. iphone 异常捕获处理

    iphone 异常捕获处理 1 void UncaughtExceptionHandler(NSException *exception) { 2 NSArray *arr = [exception ...

  8. TCP三次握手和四次挥手协议

    相对于SOCKET开发者,TCP创建过程和链接折除过程是由TCP/IP协议栈自动创建的.因此开发者并不需要控制这个过程.但是对于理解TCP底层运作机制,相当有帮助. TCP三次握手   所谓三次握手( ...

  9. ios开发--第三方整理

    一:第三方插件 1:基于响应式编程思想的oc 地址:https://github.com/ReactiveCocoa/ReactiveCocoa 2:hud提示框 地址:https://github. ...

  10. SSIS ->> 生成时间格式

    有时我们需要生成一个文件,文件名的构成是当前时间的特定字符串格式,如yyyyMMddHHmmss 当前时间变成yyyyMMddHHmmss这个格式: (DT_WSTR,4) YEAR(GETDATE( ...