Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
2580390c
K
Kernel
项目概览
openeuler
/
Kernel
接近 2 年 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
2580390c
编写于
11月 06, 2012
作者:
T
Tony Lindgren
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'dev-dt-timer' of github.com:jonhunter/linux into omap-for-v3.8/dt
上级
ad325255
9883f7c8
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
275 addition
and
39 deletion
+275
-39
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/board-generic.c
+17
-0
arch/arm/mach-omap2/timer.c
arch/arm/mach-omap2/timer.c
+170
-33
arch/arm/plat-omap/dmtimer.c
arch/arm/plat-omap/dmtimer.c
+87
-6
arch/arm/plat-omap/include/plat/dmtimer.h
arch/arm/plat-omap/include/plat/dmtimer.h
+1
-0
未找到文件。
arch/arm/mach-omap2/board-generic.c
浏览文件 @
2580390c
...
...
@@ -97,6 +97,23 @@ DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)")
.
dt_compat
=
omap3_boards_compat
,
.
restart
=
omap_prcm_restart
,
MACHINE_END
static
const
char
*
omap3_gp_boards_compat
[]
__initdata
=
{
"ti,omap3-beagle"
,
NULL
,
};
DT_MACHINE_START
(
OMAP3_GP_DT
,
"Generic OMAP3-GP (Flattened Device Tree)"
)
.
reserve
=
omap_reserve
,
.
map_io
=
omap3_map_io
,
.
init_early
=
omap3430_init_early
,
.
init_irq
=
omap_intc_of_init
,
.
handle_irq
=
omap3_intc_handle_irq
,
.
init_machine
=
omap_generic_init
,
.
timer
=
&
omap3_secure_timer
,
.
dt_compat
=
omap3_gp_boards_compat
,
.
restart
=
omap_prcm_restart
,
MACHINE_END
#endif
#ifdef CONFIG_SOC_AM33XX
...
...
arch/arm/mach-omap2/timer.c
浏览文件 @
2580390c
...
...
@@ -37,6 +37,8 @@
#include <linux/clockchips.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <asm/mach/time.h>
#include <asm/smp_twd.h>
...
...
@@ -66,11 +68,13 @@
#define OMAP3_CLKEV_SOURCE OMAP3_32K_SOURCE
#define OMAP4_CLKEV_SOURCE OMAP4_32K_SOURCE
#define OMAP3_SECURE_TIMER 12
#define TIMER_PROP_SECURE "ti,timer-secure"
#else
#define OMAP2_CLKEV_SOURCE OMAP2_MPU_SOURCE
#define OMAP3_CLKEV_SOURCE OMAP3_MPU_SOURCE
#define OMAP4_CLKEV_SOURCE OMAP4_MPU_SOURCE
#define OMAP3_SECURE_TIMER 1
#define TIMER_PROP_SECURE "ti,timer-alwon"
#endif
#define REALTIME_COUNTER_BASE 0x48243200
...
...
@@ -144,36 +148,141 @@ static struct clock_event_device clockevent_gpt = {
.
set_mode
=
omap2_gp_timer_set_mode
,
};
static
struct
property
device_disabled
=
{
.
name
=
"status"
,
.
length
=
sizeof
(
"disabled"
),
.
value
=
"disabled"
,
};
static
struct
of_device_id
omap_timer_match
[]
__initdata
=
{
{
.
compatible
=
"ti,omap2-timer"
,
},
{
}
};
static
struct
of_device_id
omap_counter_match
[]
__initdata
=
{
{
.
compatible
=
"ti,omap-counter32k"
,
},
{
}
};
/**
* omap_get_timer_dt - get a timer using device-tree
* @match - device-tree match structure for matching a device type
* @property - optional timer property to match
*
* Helper function to get a timer during early boot using device-tree for use
* as kernel system timer. Optionally, the property argument can be used to
* select a timer with a specific property. Once a timer is found then mark
* the timer node in device-tree as disabled, to prevent the kernel from
* registering this timer as a platform device and so no one else can use it.
*/
static
struct
device_node
*
__init
omap_get_timer_dt
(
struct
of_device_id
*
match
,
const
char
*
property
)
{
struct
device_node
*
np
;
for_each_matching_node
(
np
,
match
)
{
if
(
!
of_device_is_available
(
np
))
{
of_node_put
(
np
);
continue
;
}
if
(
property
&&
!
of_get_property
(
np
,
property
,
NULL
))
{
of_node_put
(
np
);
continue
;
}
prom_add_property
(
np
,
&
device_disabled
);
return
np
;
}
return
NULL
;
}
/**
* omap_dmtimer_init - initialisation function when device tree is used
*
* For secure OMAP3 devices, timers with device type "timer-secure" cannot
* be used by the kernel as they are reserved. Therefore, to prevent the
* kernel registering these devices remove them dynamically from the device
* tree on boot.
*/
void
__init
omap_dmtimer_init
(
void
)
{
struct
device_node
*
np
;
if
(
!
cpu_is_omap34xx
())
return
;
/* If we are a secure device, remove any secure timer nodes */
if
((
omap_type
()
!=
OMAP2_DEVICE_TYPE_GP
))
{
np
=
omap_get_timer_dt
(
omap_timer_match
,
"ti,timer-secure"
);
if
(
np
)
of_node_put
(
np
);
}
}
static
int
__init
omap_dm_timer_init_one
(
struct
omap_dm_timer
*
timer
,
int
gptimer_id
,
const
char
*
fck_source
)
const
char
*
fck_source
,
const
char
*
property
)
{
char
name
[
10
];
/* 10 = sizeof("gptXX_Xck0") */
const
char
*
oh_name
;
struct
device_node
*
np
;
struct
omap_hwmod
*
oh
;
struct
resource
irq_rsrc
,
mem_rsrc
;
size_t
size
;
int
res
=
0
;
int
r
;
sprintf
(
name
,
"timer%d"
,
gptimer_id
);
omap_hwmod_setup_one
(
name
);
oh
=
omap_hwmod_lookup
(
name
);
if
(
of_have_populated_dt
())
{
np
=
omap_get_timer_dt
(
omap_timer_match
,
NULL
);
if
(
!
np
)
return
-
ENODEV
;
of_property_read_string_index
(
np
,
"ti,hwmods"
,
0
,
&
oh_name
);
if
(
!
oh_name
)
return
-
ENODEV
;
timer
->
irq
=
irq_of_parse_and_map
(
np
,
0
);
if
(
!
timer
->
irq
)
return
-
ENXIO
;
timer
->
io_base
=
of_iomap
(
np
,
0
);
of_node_put
(
np
);
}
else
{
if
(
omap_dm_timer_reserve_systimer
(
gptimer_id
))
return
-
ENODEV
;
sprintf
(
name
,
"timer%d"
,
gptimer_id
);
oh_name
=
name
;
}
omap_hwmod_setup_one
(
oh_name
);
oh
=
omap_hwmod_lookup
(
oh_name
);
if
(
!
oh
)
return
-
ENODEV
;
r
=
omap_hwmod_get_resource_byname
(
oh
,
IORESOURCE_IRQ
,
NULL
,
&
irq_rsrc
);
if
(
r
)
return
-
ENXIO
;
timer
->
irq
=
irq_rsrc
.
start
;
r
=
omap_hwmod_get_resource_byname
(
oh
,
IORESOURCE_MEM
,
NULL
,
&
mem_rsrc
);
if
(
r
)
return
-
ENXIO
;
timer
->
phys_base
=
mem_rsrc
.
start
;
size
=
mem_rsrc
.
end
-
mem_rsrc
.
start
;
if
(
!
of_have_populated_dt
())
{
r
=
omap_hwmod_get_resource_byname
(
oh
,
IORESOURCE_IRQ
,
NULL
,
&
irq_rsrc
);
if
(
r
)
return
-
ENXIO
;
timer
->
irq
=
irq_rsrc
.
start
;
r
=
omap_hwmod_get_resource_byname
(
oh
,
IORESOURCE_MEM
,
NULL
,
&
mem_rsrc
);
if
(
r
)
return
-
ENXIO
;
timer
->
phys_base
=
mem_rsrc
.
start
;
size
=
mem_rsrc
.
end
-
mem_rsrc
.
start
;
/* Static mapping, never released */
timer
->
io_base
=
ioremap
(
timer
->
phys_base
,
size
);
}
/* Static mapping, never released */
timer
->
io_base
=
ioremap
(
timer
->
phys_base
,
size
);
if
(
!
timer
->
io_base
)
return
-
ENXIO
;
...
...
@@ -184,9 +293,7 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
omap_hwmod_enable
(
oh
);
if
(
omap_dm_timer_reserve_systimer
(
gptimer_id
))
return
-
ENODEV
;
/* FIXME: Need to remove hard-coded test on timer ID */
if
(
gptimer_id
!=
12
)
{
struct
clk
*
src
;
...
...
@@ -196,8 +303,8 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
}
else
{
res
=
__omap_dm_timer_set_source
(
timer
->
fclk
,
src
);
if
(
IS_ERR_VALUE
(
res
))
pr_warn
ing
(
"%s: timer%i
cannot set source
\n
"
,
__func__
,
gptimer_id
);
pr_warn
(
"%s: %s
cannot set source
\n
"
,
__func__
,
oh
->
name
);
clk_put
(
src
);
}
}
...
...
@@ -213,11 +320,12 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
}
static
void
__init
omap2_gp_clockevent_init
(
int
gptimer_id
,
const
char
*
fck_source
)
const
char
*
fck_source
,
const
char
*
property
)
{
int
res
;
res
=
omap_dm_timer_init_one
(
&
clkev
,
gptimer_id
,
fck_source
);
res
=
omap_dm_timer_init_one
(
&
clkev
,
gptimer_id
,
fck_source
,
property
);
BUG_ON
(
res
);
omap2_gp_timer_irq
.
dev_id
=
&
clkev
;
...
...
@@ -274,10 +382,25 @@ static u32 notrace dmtimer_read_sched_clock(void)
static
int
__init
omap2_sync32k_clocksource_init
(
void
)
{
int
ret
;
struct
device_node
*
np
=
NULL
;
struct
omap_hwmod
*
oh
;
void
__iomem
*
vbase
;
const
char
*
oh_name
=
"counter_32k"
;
/*
* If device-tree is present, then search the DT blob
* to see if the 32kHz counter is supported.
*/
if
(
of_have_populated_dt
())
{
np
=
omap_get_timer_dt
(
omap_counter_match
,
NULL
);
if
(
!
np
)
return
-
ENODEV
;
of_property_read_string_index
(
np
,
"ti,hwmods"
,
0
,
&
oh_name
);
if
(
!
oh_name
)
return
-
ENODEV
;
}
/*
* First check hwmod data is available for sync32k counter
*/
...
...
@@ -287,7 +410,13 @@ static int __init omap2_sync32k_clocksource_init(void)
omap_hwmod_setup_one
(
oh_name
);
vbase
=
omap_hwmod_get_mpu_rt_va
(
oh
);
if
(
np
)
{
vbase
=
of_iomap
(
np
,
0
);
of_node_put
(
np
);
}
else
{
vbase
=
omap_hwmod_get_mpu_rt_va
(
oh
);
}
if
(
!
vbase
)
{
pr_warn
(
"%s: failed to get counter_32k resource
\n
"
,
__func__
);
return
-
ENXIO
;
...
...
@@ -321,7 +450,7 @@ static void __init omap2_gptimer_clocksource_init(int gptimer_id,
{
int
res
;
res
=
omap_dm_timer_init_one
(
&
clksrc
,
gptimer_id
,
fck_source
);
res
=
omap_dm_timer_init_one
(
&
clksrc
,
gptimer_id
,
fck_source
,
NULL
);
BUG_ON
(
res
);
__omap_dm_timer_load_start
(
&
clksrc
,
...
...
@@ -433,11 +562,12 @@ static inline void __init realtime_counter_init(void)
{}
#endif
#define OMAP_SYS_TIMER_INIT(name, clkev_nr, clkev_src,
\
#define OMAP_SYS_TIMER_INIT(name, clkev_nr, clkev_src,
clkev_prop,
\
clksrc_nr, clksrc_src) \
static void __init omap##name##_timer_init(void) \
{ \
omap2_gp_clockevent_init((clkev_nr), clkev_src); \
omap_dmtimer_init(); \
omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \
omap2_clocksource_init((clksrc_nr), clksrc_src); \
}
...
...
@@ -447,20 +577,23 @@ struct sys_timer omap##name##_timer = { \
};
#ifdef CONFIG_ARCH_OMAP2
OMAP_SYS_TIMER_INIT
(
2
,
1
,
OMAP2_CLKEV_SOURCE
,
2
,
OMAP2_MPU_SOURCE
)
OMAP_SYS_TIMER_INIT
(
2
,
1
,
OMAP2_CLKEV_SOURCE
,
"ti,timer-alwon"
,
2
,
OMAP2_MPU_SOURCE
)
OMAP_SYS_TIMER
(
2
)
#endif
#ifdef CONFIG_ARCH_OMAP3
OMAP_SYS_TIMER_INIT
(
3
,
1
,
OMAP3_CLKEV_SOURCE
,
2
,
OMAP3_MPU_SOURCE
)
OMAP_SYS_TIMER_INIT
(
3
,
1
,
OMAP3_CLKEV_SOURCE
,
"ti,timer-alwon"
,
2
,
OMAP3_MPU_SOURCE
)
OMAP_SYS_TIMER
(
3
)
OMAP_SYS_TIMER_INIT
(
3
_secure
,
OMAP3_SECURE_TIMER
,
OMAP3_CLKEV_SOURCE
,
2
,
OMAP3_MPU_SOURCE
)
TIMER_PROP_SECURE
,
2
,
OMAP3_MPU_SOURCE
)
OMAP_SYS_TIMER
(
3
_secure
)
#endif
#ifdef CONFIG_SOC_AM33XX
OMAP_SYS_TIMER_INIT
(
3
_am33xx
,
1
,
OMAP4_MPU_SOURCE
,
2
,
OMAP4_MPU_SOURCE
)
OMAP_SYS_TIMER_INIT
(
3
_am33xx
,
1
,
OMAP4_MPU_SOURCE
,
"ti,timer-alwon"
,
2
,
OMAP4_MPU_SOURCE
)
OMAP_SYS_TIMER
(
3
_am33xx
)
#endif
...
...
@@ -472,7 +605,7 @@ static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
static
void
__init
omap4_timer_init
(
void
)
{
omap2_gp_clockevent_init
(
1
,
OMAP4_CLKEV_SOURCE
);
omap2_gp_clockevent_init
(
1
,
OMAP4_CLKEV_SOURCE
,
"ti,timer-alwon"
);
omap2_clocksource_init
(
2
,
OMAP4_MPU_SOURCE
);
#ifdef CONFIG_LOCAL_TIMERS
/* Local timers are not supprted on OMAP4430 ES1.0 */
...
...
@@ -498,7 +631,7 @@ static void __init omap5_timer_init(void)
{
int
err
;
omap2_gp_clockevent_init
(
1
,
OMAP4_CLKEV_SOURCE
);
omap2_gp_clockevent_init
(
1
,
OMAP4_CLKEV_SOURCE
,
"ti,timer-alwon"
);
omap2_clocksource_init
(
2
,
OMAP4_MPU_SOURCE
);
realtime_counter_init
();
...
...
@@ -583,6 +716,10 @@ static int __init omap2_dm_timer_init(void)
{
int
ret
;
/* If dtb is there, the devices will be created dynamically */
if
(
of_have_populated_dt
())
return
-
ENODEV
;
ret
=
omap_hwmod_for_each_by_class
(
"timer"
,
omap_timer_init
,
NULL
);
if
(
unlikely
(
ret
))
{
pr_err
(
"%s: device registration failed.
\n
"
,
__func__
);
...
...
arch/arm/plat-omap/dmtimer.c
浏览文件 @
2580390c
...
...
@@ -40,6 +40,8 @@
#include <linux/device.h>
#include <linux/err.h>
#include <linux/pm_runtime.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <plat/dmtimer.h>
#include <plat/omap-pm.h>
...
...
@@ -212,6 +214,13 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)
unsigned
long
flags
;
int
ret
=
0
;
/* Requesting timer by ID is not supported when device tree is used */
if
(
of_have_populated_dt
())
{
pr_warn
(
"%s: Please use omap_dm_timer_request_by_cap()
\n
"
,
__func__
);
return
NULL
;
}
spin_lock_irqsave
(
&
dm_timer_lock
,
flags
);
list_for_each_entry
(
t
,
&
omap_timer_list
,
node
)
{
if
(
t
->
pdev
->
id
==
id
&&
!
t
->
reserved
)
{
...
...
@@ -237,6 +246,58 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)
}
EXPORT_SYMBOL_GPL
(
omap_dm_timer_request_specific
);
/**
* omap_dm_timer_request_by_cap - Request a timer by capability
* @cap: Bit mask of capabilities to match
*
* Find a timer based upon capabilities bit mask. Callers of this function
* should use the definitions found in the plat/dmtimer.h file under the
* comment "timer capabilities used in hwmod database". Returns pointer to
* timer handle on success and a NULL pointer on failure.
*/
struct
omap_dm_timer
*
omap_dm_timer_request_by_cap
(
u32
cap
)
{
struct
omap_dm_timer
*
timer
=
NULL
,
*
t
;
unsigned
long
flags
;
if
(
!
cap
)
return
NULL
;
spin_lock_irqsave
(
&
dm_timer_lock
,
flags
);
list_for_each_entry
(
t
,
&
omap_timer_list
,
node
)
{
if
((
!
t
->
reserved
)
&&
((
t
->
capability
&
cap
)
==
cap
))
{
/*
* If timer is not NULL, we have already found one timer
* but it was not an exact match because it had more
* capabilites that what was required. Therefore,
* unreserve the last timer found and see if this one
* is a better match.
*/
if
(
timer
)
timer
->
reserved
=
0
;
timer
=
t
;
timer
->
reserved
=
1
;
/* Exit loop early if we find an exact match */
if
(
t
->
capability
==
cap
)
break
;
}
}
spin_unlock_irqrestore
(
&
dm_timer_lock
,
flags
);
if
(
timer
&&
omap_dm_timer_prepare
(
timer
))
{
timer
->
reserved
=
0
;
timer
=
NULL
;
}
if
(
!
timer
)
pr_debug
(
"%s: timer request failed!
\n
"
,
__func__
);
return
timer
;
}
EXPORT_SYMBOL_GPL
(
omap_dm_timer_request_by_cap
);
int
omap_dm_timer_free
(
struct
omap_dm_timer
*
timer
)
{
if
(
unlikely
(
!
timer
))
...
...
@@ -414,7 +475,7 @@ int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
* use the clock framework to set the parent clock. To be removed
* once OMAP1 migrated to using clock framework for dmtimers
*/
if
(
pdata
->
set_timer_src
)
if
(
pdata
&&
pdata
->
set_timer_src
)
return
pdata
->
set_timer_src
(
timer
->
pdev
,
source
);
fclk
=
clk_get
(
&
timer
->
pdev
->
dev
,
"fck"
);
...
...
@@ -695,7 +756,7 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev)
struct
device
*
dev
=
&
pdev
->
dev
;
struct
dmtimer_platform_data
*
pdata
=
pdev
->
dev
.
platform_data
;
if
(
!
pdata
)
{
if
(
!
pdata
&&
!
dev
->
of_node
)
{
dev_err
(
dev
,
"%s: no platform data.
\n
"
,
__func__
);
return
-
ENODEV
;
}
...
...
@@ -724,11 +785,23 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev)
return
-
ENOMEM
;
}
timer
->
id
=
pdev
->
id
;
if
(
dev
->
of_node
)
{
if
(
of_find_property
(
dev
->
of_node
,
"ti,timer-alwon"
,
NULL
))
timer
->
capability
|=
OMAP_TIMER_ALWON
;
if
(
of_find_property
(
dev
->
of_node
,
"ti,timer-dsp"
,
NULL
))
timer
->
capability
|=
OMAP_TIMER_HAS_DSP_IRQ
;
if
(
of_find_property
(
dev
->
of_node
,
"ti,timer-pwm"
,
NULL
))
timer
->
capability
|=
OMAP_TIMER_HAS_PWM
;
if
(
of_find_property
(
dev
->
of_node
,
"ti,timer-secure"
,
NULL
))
timer
->
capability
|=
OMAP_TIMER_SECURE
;
}
else
{
timer
->
id
=
pdev
->
id
;
timer
->
capability
=
pdata
->
timer_capability
;
timer
->
reserved
=
omap_dm_timer_reserved_systimer
(
timer
->
id
);
}
timer
->
irq
=
irq
->
start
;
timer
->
reserved
=
omap_dm_timer_reserved_systimer
(
timer
->
id
);
timer
->
pdev
=
pdev
;
timer
->
capability
=
pdata
->
timer_capability
;
/* Skip pm_runtime_enable for OMAP1 */
if
(
!
(
timer
->
capability
&
OMAP_TIMER_NEEDS_RESET
))
{
...
...
@@ -768,7 +841,8 @@ static int __devexit omap_dm_timer_remove(struct platform_device *pdev)
spin_lock_irqsave
(
&
dm_timer_lock
,
flags
);
list_for_each_entry
(
timer
,
&
omap_timer_list
,
node
)
if
(
timer
->
pdev
->
id
==
pdev
->
id
)
{
if
(
!
strcmp
(
dev_name
(
&
timer
->
pdev
->
dev
),
dev_name
(
&
pdev
->
dev
)))
{
list_del
(
&
timer
->
node
);
ret
=
0
;
break
;
...
...
@@ -778,11 +852,18 @@ static int __devexit omap_dm_timer_remove(struct platform_device *pdev)
return
ret
;
}
static
const
struct
of_device_id
omap_timer_match
[]
=
{
{
.
compatible
=
"ti,omap2-timer"
,
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
omap_timer_match
);
static
struct
platform_driver
omap_dm_timer_driver
=
{
.
probe
=
omap_dm_timer_probe
,
.
remove
=
__devexit_p
(
omap_dm_timer_remove
),
.
driver
=
{
.
name
=
"omap_timer"
,
.
of_match_table
=
of_match_ptr
(
omap_timer_match
),
},
};
...
...
arch/arm/plat-omap/include/plat/dmtimer.h
浏览文件 @
2580390c
...
...
@@ -99,6 +99,7 @@ struct dmtimer_platform_data {
int
omap_dm_timer_reserve_systimer
(
int
id
);
struct
omap_dm_timer
*
omap_dm_timer_request
(
void
);
struct
omap_dm_timer
*
omap_dm_timer_request_specific
(
int
timer_id
);
struct
omap_dm_timer
*
omap_dm_timer_request_by_cap
(
u32
cap
);
int
omap_dm_timer_free
(
struct
omap_dm_timer
*
timer
);
void
omap_dm_timer_enable
(
struct
omap_dm_timer
*
timer
);
void
omap_dm_timer_disable
(
struct
omap_dm_timer
*
timer
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录