Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
cbaaee80
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
161
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
cbaaee80
编写于
2月 13, 2016
作者:
T
Takashi Iwai
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'topic/core-fixes' into for-next
上级
fbeac84d
f65e0d29
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
123 addition
and
145 deletion
+123
-145
sound/core/timer.c
sound/core/timer.c
+123
-145
未找到文件。
sound/core/timer.c
浏览文件 @
cbaaee80
...
...
@@ -305,8 +305,6 @@ int snd_timer_open(struct snd_timer_instance **ti,
return
0
;
}
static
int
_snd_timer_stop
(
struct
snd_timer_instance
*
timeri
,
int
event
);
/*
* close a timer instance
*/
...
...
@@ -318,25 +316,14 @@ int snd_timer_close(struct snd_timer_instance *timeri)
if
(
snd_BUG_ON
(
!
timeri
))
return
-
ENXIO
;
mutex_lock
(
&
register_mutex
);
list_del
(
&
timeri
->
open_list
);
/* force to stop the timer */
snd_timer_stop
(
timeri
);
if
(
timeri
->
flags
&
SNDRV_TIMER_IFLG_SLAVE
)
{
/* wait, until the active callback is finished */
spin_lock_irq
(
&
slave_active_lock
);
while
(
timeri
->
flags
&
SNDRV_TIMER_IFLG_CALLBACK
)
{
spin_unlock_irq
(
&
slave_active_lock
);
udelay
(
10
);
spin_lock_irq
(
&
slave_active_lock
);
}
spin_unlock_irq
(
&
slave_active_lock
);
mutex_lock
(
&
register_mutex
);
list_del
(
&
timeri
->
open_list
);
mutex_unlock
(
&
register_mutex
);
}
else
{
timer
=
timeri
->
timer
;
if
(
snd_BUG_ON
(
!
timer
))
goto
out
;
timer
=
timeri
->
timer
;
if
(
timer
)
{
/* wait, until the active callback is finished */
spin_lock_irq
(
&
timer
->
lock
);
while
(
timeri
->
flags
&
SNDRV_TIMER_IFLG_CALLBACK
)
{
...
...
@@ -345,11 +332,7 @@ int snd_timer_close(struct snd_timer_instance *timeri)
spin_lock_irq
(
&
timer
->
lock
);
}
spin_unlock_irq
(
&
timer
->
lock
);
mutex_lock
(
&
register_mutex
);
list_del
(
&
timeri
->
open_list
);
if
(
list_empty
(
&
timer
->
open_list_head
)
&&
timer
->
hw
.
close
)
timer
->
hw
.
close
(
timer
);
/* remove slave links */
spin_lock_irq
(
&
slave_active_lock
);
spin_lock
(
&
timer
->
lock
);
...
...
@@ -363,18 +346,27 @@ int snd_timer_close(struct snd_timer_instance *timeri)
}
spin_unlock
(
&
timer
->
lock
);
spin_unlock_irq
(
&
slave_active_lock
);
/* release a card refcount for safe disconnection */
if
(
timer
->
card
)
put_device
(
&
timer
->
card
->
card_dev
);
mutex_unlock
(
&
register_mutex
)
;
/* slave doesn't need to release timer resources below */
if
(
timeri
->
flags
&
SNDRV_TIMER_IFLG_SLAVE
)
timer
=
NULL
;
}
out:
if
(
timeri
->
private_free
)
timeri
->
private_free
(
timeri
);
kfree
(
timeri
->
owner
);
kfree
(
timeri
);
if
(
timer
)
if
(
timer
)
{
if
(
list_empty
(
&
timer
->
open_list_head
)
&&
timer
->
hw
.
close
)
timer
->
hw
.
close
(
timer
);
/* release a card refcount for safe disconnection */
if
(
timer
->
card
)
put_device
(
&
timer
->
card
->
card_dev
);
module_put
(
timer
->
module
);
}
mutex_unlock
(
&
register_mutex
);
return
0
;
}
...
...
@@ -395,7 +387,6 @@ unsigned long snd_timer_resolution(struct snd_timer_instance *timeri)
static
void
snd_timer_notify1
(
struct
snd_timer_instance
*
ti
,
int
event
)
{
struct
snd_timer
*
timer
;
unsigned
long
flags
;
unsigned
long
resolution
=
0
;
struct
snd_timer_instance
*
ts
;
struct
timespec
tstamp
;
...
...
@@ -419,34 +410,66 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
return
;
if
(
timer
->
hw
.
flags
&
SNDRV_TIMER_HW_SLAVE
)
return
;
spin_lock_irqsave
(
&
timer
->
lock
,
flags
);
list_for_each_entry
(
ts
,
&
ti
->
slave_active_head
,
active_list
)
if
(
ts
->
ccallback
)
ts
->
ccallback
(
ts
,
event
+
100
,
&
tstamp
,
resolution
);
spin_unlock_irqrestore
(
&
timer
->
lock
,
flags
);
}
static
int
snd_timer_start1
(
struct
snd_timer
*
timer
,
struct
snd_timer_instance
*
timeri
,
unsigned
long
sticks
)
/* start/continue a master timer */
static
int
snd_timer_start1
(
struct
snd_timer_instance
*
timeri
,
bool
start
,
unsigned
long
ticks
)
{
struct
snd_timer
*
timer
;
int
result
;
unsigned
long
flags
;
timer
=
timeri
->
timer
;
if
(
!
timer
)
return
-
EINVAL
;
spin_lock_irqsave
(
&
timer
->
lock
,
flags
);
if
(
timer
->
card
&&
timer
->
card
->
shutdown
)
{
result
=
-
ENODEV
;
goto
unlock
;
}
if
(
timeri
->
flags
&
(
SNDRV_TIMER_IFLG_RUNNING
|
SNDRV_TIMER_IFLG_START
))
{
result
=
-
EBUSY
;
goto
unlock
;
}
if
(
start
)
timeri
->
ticks
=
timeri
->
cticks
=
ticks
;
else
if
(
!
timeri
->
cticks
)
timeri
->
cticks
=
1
;
timeri
->
pticks
=
0
;
list_move_tail
(
&
timeri
->
active_list
,
&
timer
->
active_list_head
);
if
(
timer
->
running
)
{
if
(
timer
->
hw
.
flags
&
SNDRV_TIMER_HW_SLAVE
)
goto
__start_now
;
timer
->
flags
|=
SNDRV_TIMER_FLG_RESCHED
;
timeri
->
flags
|=
SNDRV_TIMER_IFLG_START
;
re
turn
1
;
/* delayed start */
re
sult
=
1
;
/* delayed start */
}
else
{
timer
->
sticks
=
sticks
;
if
(
start
)
timer
->
sticks
=
ticks
;
timer
->
hw
.
start
(
timer
);
__start_now:
timer
->
running
++
;
timeri
->
flags
|=
SNDRV_TIMER_IFLG_RUNNING
;
re
turn
0
;
re
sult
=
0
;
}
snd_timer_notify1
(
timeri
,
start
?
SNDRV_TIMER_EVENT_START
:
SNDRV_TIMER_EVENT_CONTINUE
);
unlock:
spin_unlock_irqrestore
(
&
timer
->
lock
,
flags
);
return
result
;
}
static
int
snd_timer_start_slave
(
struct
snd_timer_instance
*
timeri
)
/* start/continue a slave timer */
static
int
snd_timer_start_slave
(
struct
snd_timer_instance
*
timeri
,
bool
start
)
{
unsigned
long
flags
;
...
...
@@ -460,88 +483,37 @@ static int snd_timer_start_slave(struct snd_timer_instance *timeri)
spin_lock
(
&
timeri
->
timer
->
lock
);
list_add_tail
(
&
timeri
->
active_list
,
&
timeri
->
master
->
slave_active_head
);
snd_timer_notify1
(
timeri
,
start
?
SNDRV_TIMER_EVENT_START
:
SNDRV_TIMER_EVENT_CONTINUE
);
spin_unlock
(
&
timeri
->
timer
->
lock
);
}
spin_unlock_irqrestore
(
&
slave_active_lock
,
flags
);
return
1
;
/* delayed start */
}
/*
* start the timer instance
*/
int
snd_timer_start
(
struct
snd_timer_instance
*
timeri
,
unsigned
int
ticks
)
/* stop/pause a master timer */
static
int
snd_timer_stop1
(
struct
snd_timer_instance
*
timeri
,
bool
stop
)
{
struct
snd_timer
*
timer
;
int
result
=
-
EINVAL
;
int
result
=
0
;
unsigned
long
flags
;
if
(
timeri
==
NULL
||
ticks
<
1
)
return
-
EINVAL
;
if
(
timeri
->
flags
&
SNDRV_TIMER_IFLG_SLAVE
)
{
result
=
snd_timer_start_slave
(
timeri
);
if
(
result
>=
0
)
snd_timer_notify1
(
timeri
,
SNDRV_TIMER_EVENT_START
);
return
result
;
}
timer
=
timeri
->
timer
;
if
(
timer
==
NULL
)
return
-
EINVAL
;
if
(
timer
->
card
&&
timer
->
card
->
shutdown
)
return
-
ENODEV
;
spin_lock_irqsave
(
&
timer
->
lock
,
flags
);
if
(
timeri
->
flags
&
(
SNDRV_TIMER_IFLG_RUNNING
|
SNDRV_TIMER_IFLG_START
))
{
result
=
-
EBUSY
;
goto
unlock
;
}
timeri
->
ticks
=
timeri
->
cticks
=
ticks
;
timeri
->
pticks
=
0
;
result
=
snd_timer_start1
(
timer
,
timeri
,
ticks
);
unlock:
spin_unlock_irqrestore
(
&
timer
->
lock
,
flags
);
if
(
result
>=
0
)
snd_timer_notify1
(
timeri
,
SNDRV_TIMER_EVENT_START
);
return
result
;
}
static
int
_snd_timer_stop
(
struct
snd_timer_instance
*
timeri
,
int
event
)
{
struct
snd_timer
*
timer
;
unsigned
long
flags
;
if
(
snd_BUG_ON
(
!
timeri
))
return
-
ENXIO
;
if
(
timeri
->
flags
&
SNDRV_TIMER_IFLG_SLAVE
)
{
spin_lock_irqsave
(
&
slave_active_lock
,
flags
);
if
(
!
(
timeri
->
flags
&
SNDRV_TIMER_IFLG_RUNNING
))
{
spin_unlock_irqrestore
(
&
slave_active_lock
,
flags
);
return
-
EBUSY
;
}
if
(
timeri
->
timer
)
spin_lock
(
&
timeri
->
timer
->
lock
);
timeri
->
flags
&=
~
SNDRV_TIMER_IFLG_RUNNING
;
list_del_init
(
&
timeri
->
ack_list
);
list_del_init
(
&
timeri
->
active_list
);
if
(
timeri
->
timer
)
spin_unlock
(
&
timeri
->
timer
->
lock
);
spin_unlock_irqrestore
(
&
slave_active_lock
,
flags
);
goto
__end
;
}
timer
=
timeri
->
timer
;
if
(
!
timer
)
return
-
EINVAL
;
spin_lock_irqsave
(
&
timer
->
lock
,
flags
);
if
(
!
(
timeri
->
flags
&
(
SNDRV_TIMER_IFLG_RUNNING
|
SNDRV_TIMER_IFLG_START
)))
{
spin_unlock_irqrestore
(
&
timer
->
lock
,
flags
)
;
return
-
EBUSY
;
result
=
-
EBUSY
;
goto
unlock
;
}
list_del_init
(
&
timeri
->
ack_list
);
list_del_init
(
&
timeri
->
active_list
);
if
(
timer
->
card
&&
timer
->
card
->
shutdown
)
{
spin_unlock_irqrestore
(
&
timer
->
lock
,
flags
);
return
0
;
if
(
timer
->
card
&&
timer
->
card
->
shutdown
)
goto
unlock
;
if
(
stop
)
{
timeri
->
cticks
=
timeri
->
ticks
;
timeri
->
pticks
=
0
;
}
if
((
timeri
->
flags
&
SNDRV_TIMER_IFLG_RUNNING
)
&&
!
(
--
timer
->
running
))
{
...
...
@@ -556,13 +528,49 @@ static int _snd_timer_stop(struct snd_timer_instance *timeri, int event)
}
}
timeri
->
flags
&=
~
(
SNDRV_TIMER_IFLG_RUNNING
|
SNDRV_TIMER_IFLG_START
);
snd_timer_notify1
(
timeri
,
stop
?
SNDRV_TIMER_EVENT_STOP
:
SNDRV_TIMER_EVENT_CONTINUE
);
unlock:
spin_unlock_irqrestore
(
&
timer
->
lock
,
flags
);
__end:
if
(
event
!=
SNDRV_TIMER_EVENT_RESOLUTION
)
snd_timer_notify1
(
timeri
,
event
);
return
result
;
}
/* stop/pause a slave timer */
static
int
snd_timer_stop_slave
(
struct
snd_timer_instance
*
timeri
,
bool
stop
)
{
unsigned
long
flags
;
spin_lock_irqsave
(
&
slave_active_lock
,
flags
);
if
(
!
(
timeri
->
flags
&
SNDRV_TIMER_IFLG_RUNNING
))
{
spin_unlock_irqrestore
(
&
slave_active_lock
,
flags
);
return
-
EBUSY
;
}
timeri
->
flags
&=
~
SNDRV_TIMER_IFLG_RUNNING
;
if
(
timeri
->
timer
)
{
spin_lock
(
&
timeri
->
timer
->
lock
);
list_del_init
(
&
timeri
->
ack_list
);
list_del_init
(
&
timeri
->
active_list
);
snd_timer_notify1
(
timeri
,
stop
?
SNDRV_TIMER_EVENT_STOP
:
SNDRV_TIMER_EVENT_CONTINUE
);
spin_unlock
(
&
timeri
->
timer
->
lock
);
}
spin_unlock_irqrestore
(
&
slave_active_lock
,
flags
);
return
0
;
}
/*
* start the timer instance
*/
int
snd_timer_start
(
struct
snd_timer_instance
*
timeri
,
unsigned
int
ticks
)
{
if
(
timeri
==
NULL
||
ticks
<
1
)
return
-
EINVAL
;
if
(
timeri
->
flags
&
SNDRV_TIMER_IFLG_SLAVE
)
return
snd_timer_start_slave
(
timeri
,
true
);
else
return
snd_timer_start1
(
timeri
,
true
,
ticks
);
}
/*
* stop the timer instance.
*
...
...
@@ -570,21 +578,10 @@ static int _snd_timer_stop(struct snd_timer_instance *timeri, int event)
*/
int
snd_timer_stop
(
struct
snd_timer_instance
*
timeri
)
{
struct
snd_timer
*
timer
;
unsigned
long
flags
;
int
err
;
err
=
_snd_timer_stop
(
timeri
,
SNDRV_TIMER_EVENT_STOP
);
if
(
err
<
0
)
return
err
;
timer
=
timeri
->
timer
;
if
(
!
timer
)
return
-
EINVAL
;
spin_lock_irqsave
(
&
timer
->
lock
,
flags
);
timeri
->
cticks
=
timeri
->
ticks
;
timeri
->
pticks
=
0
;
spin_unlock_irqrestore
(
&
timer
->
lock
,
flags
);
return
0
;
if
(
timeri
->
flags
&
SNDRV_TIMER_IFLG_SLAVE
)
return
snd_timer_stop_slave
(
timeri
,
true
);
else
return
snd_timer_stop1
(
timeri
,
true
);
}
/*
...
...
@@ -592,32 +589,10 @@ int snd_timer_stop(struct snd_timer_instance *timeri)
*/
int
snd_timer_continue
(
struct
snd_timer_instance
*
timeri
)
{
struct
snd_timer
*
timer
;
int
result
=
-
EINVAL
;
unsigned
long
flags
;
if
(
timeri
==
NULL
)
return
result
;
if
(
timeri
->
flags
&
SNDRV_TIMER_IFLG_SLAVE
)
return
snd_timer_start_slave
(
timeri
);
timer
=
timeri
->
timer
;
if
(
!
timer
)
return
-
EINVAL
;
if
(
timer
->
card
&&
timer
->
card
->
shutdown
)
return
-
ENODEV
;
spin_lock_irqsave
(
&
timer
->
lock
,
flags
);
if
(
timeri
->
flags
&
SNDRV_TIMER_IFLG_RUNNING
)
{
result
=
-
EBUSY
;
goto
unlock
;
}
if
(
!
timeri
->
cticks
)
timeri
->
cticks
=
1
;
timeri
->
pticks
=
0
;
result
=
snd_timer_start1
(
timer
,
timeri
,
timer
->
sticks
);
unlock:
spin_unlock_irqrestore
(
&
timer
->
lock
,
flags
);
snd_timer_notify1
(
timeri
,
SNDRV_TIMER_EVENT_CONTINUE
);
return
result
;
return
snd_timer_start_slave
(
timeri
,
false
);
else
return
snd_timer_start1
(
timeri
,
false
,
0
);
}
/*
...
...
@@ -625,7 +600,10 @@ int snd_timer_continue(struct snd_timer_instance *timeri)
*/
int
snd_timer_pause
(
struct
snd_timer_instance
*
timeri
)
{
return
_snd_timer_stop
(
timeri
,
SNDRV_TIMER_EVENT_PAUSE
);
if
(
timeri
->
flags
&
SNDRV_TIMER_IFLG_SLAVE
)
return
snd_timer_stop_slave
(
timeri
,
false
);
else
return
snd_timer_stop1
(
timeri
,
false
);
}
/*
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录