Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
b566762a
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
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看板
提交
b566762a
编写于
10年前
作者:
T
Takashi Iwai
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'topic/seq-autoload' into for-next
上级
e2009536
d5129f33
无相关合并请求
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
79 addition
and
33 deletion
+79
-33
include/sound/seq_kernel.h
include/sound/seq_kernel.h
+4
-0
sound/core/seq/seq.c
sound/core/seq/seq.c
+3
-2
sound/core/seq/seq_device.c
sound/core/seq/seq_device.c
+72
-31
未找到文件。
include/sound/seq_kernel.h
浏览文件 @
b566762a
...
...
@@ -108,9 +108,13 @@ int snd_seq_event_port_detach(int client, int port);
#ifdef CONFIG_MODULES
void
snd_seq_autoload_lock
(
void
);
void
snd_seq_autoload_unlock
(
void
);
void
snd_seq_autoload_init
(
void
);
#define snd_seq_autoload_exit() snd_seq_autoload_lock()
#else
#define snd_seq_autoload_lock()
#define snd_seq_autoload_unlock()
#define snd_seq_autoload_init()
#define snd_seq_autoload_exit()
#endif
#endif
/* __SOUND_SEQ_KERNEL_H */
This diff is collapsed.
Click to expand it.
sound/core/seq/seq.c
浏览文件 @
b566762a
...
...
@@ -86,7 +86,6 @@ static int __init alsa_seq_init(void)
{
int
err
;
snd_seq_autoload_lock
();
if
((
err
=
client_init_data
())
<
0
)
goto
error
;
...
...
@@ -110,8 +109,8 @@ static int __init alsa_seq_init(void)
if
((
err
=
snd_seq_system_client_init
())
<
0
)
goto
error
;
snd_seq_autoload_init
();
error:
snd_seq_autoload_unlock
();
return
err
;
}
...
...
@@ -131,6 +130,8 @@ static void __exit alsa_seq_exit(void)
/* release event memory */
snd_sequencer_memory_done
();
snd_seq_autoload_exit
();
}
module_init
(
alsa_seq_init
)
...
...
This diff is collapsed.
Click to expand it.
sound/core/seq/seq_device.c
浏览文件 @
b566762a
...
...
@@ -56,6 +56,7 @@ MODULE_LICENSE("GPL");
#define DRIVER_LOADED (1<<0)
#define DRIVER_REQUESTED (1<<1)
#define DRIVER_LOCKED (1<<2)
#define DRIVER_REQUESTING (1<<3)
struct
ops_list
{
char
id
[
ID_LEN
];
/* driver id */
...
...
@@ -127,42 +128,82 @@ static void snd_seq_device_info(struct snd_info_entry *entry,
#ifdef CONFIG_MODULES
/* avoid auto-loading during module_init() */
static
int
snd_seq_in_init
;
static
atomic_t
snd_seq_in_init
=
ATOMIC_INIT
(
1
);
/* blocked as default */
void
snd_seq_autoload_lock
(
void
)
{
snd_seq_in_init
++
;
atomic_inc
(
&
snd_seq_in_init
)
;
}
void
snd_seq_autoload_unlock
(
void
)
{
snd_seq_in_init
--
;
atomic_dec
(
&
snd_seq_in_init
)
;
}
#endif
void
snd_seq_device_
load_drivers
(
void
)
static
void
auto
load_drivers
(
void
)
{
#ifdef CONFIG_MODULES
struct
ops_list
*
ops
;
/* avoid reentrance */
if
(
atomic_inc_return
(
&
snd_seq_in_init
)
==
1
)
{
struct
ops_list
*
ops
;
mutex_lock
(
&
ops_mutex
);
list_for_each_entry
(
ops
,
&
opslist
,
list
)
{
if
((
ops
->
driver
&
DRIVER_REQUESTING
)
&&
!
(
ops
->
driver
&
DRIVER_REQUESTED
))
{
ops
->
used
++
;
mutex_unlock
(
&
ops_mutex
);
ops
->
driver
|=
DRIVER_REQUESTED
;
request_module
(
"snd-%s"
,
ops
->
id
);
mutex_lock
(
&
ops_mutex
);
ops
->
used
--
;
}
}
mutex_unlock
(
&
ops_mutex
);
}
atomic_dec
(
&
snd_seq_in_init
);
}
/* Calling request_module during module_init()
* may cause blocking.
*/
if
(
snd_seq_in_init
)
return
;
static
void
call_autoload
(
struct
work_struct
*
work
)
{
autoload_drivers
();
}
mutex_lock
(
&
ops_mutex
);
list_for_each_entry
(
ops
,
&
opslist
,
list
)
{
if
(
!
(
ops
->
driver
&
DRIVER_LOADED
)
&&
!
(
ops
->
driver
&
DRIVER_REQUESTED
))
{
ops
->
used
++
;
mutex_unlock
(
&
ops_mutex
);
ops
->
driver
|=
DRIVER_REQUESTED
;
request_module
(
"snd-%s"
,
ops
->
id
);
mutex_lock
(
&
ops_mutex
);
ops
->
used
--
;
}
static
DECLARE_WORK
(
autoload_work
,
call_autoload
);
static
void
try_autoload
(
struct
ops_list
*
ops
)
{
if
(
!
ops
->
driver
)
{
ops
->
driver
|=
DRIVER_REQUESTING
;
schedule_work
(
&
autoload_work
);
}
}
static
void
queue_autoload_drivers
(
void
)
{
struct
ops_list
*
ops
;
mutex_lock
(
&
ops_mutex
);
list_for_each_entry
(
ops
,
&
opslist
,
list
)
try_autoload
(
ops
);
mutex_unlock
(
&
ops_mutex
);
}
void
snd_seq_autoload_init
(
void
)
{
atomic_dec
(
&
snd_seq_in_init
);
#ifdef CONFIG_SND_SEQUENCER_MODULE
/* initial autoload only when snd-seq is a module */
queue_autoload_drivers
();
#endif
}
#else
#define try_autoload(ops)
/* NOP */
#endif
void
snd_seq_device_load_drivers
(
void
)
{
#ifdef CONFIG_MODULES
queue_autoload_drivers
();
flush_work
(
&
autoload_work
);
#endif
}
...
...
@@ -214,13 +255,14 @@ int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize,
ops
->
num_devices
++
;
mutex_unlock
(
&
ops
->
reg_mutex
);
unlock_driver
(
ops
);
if
((
err
=
snd_device_new
(
card
,
SNDRV_DEV_SEQUENCER
,
dev
,
&
dops
))
<
0
)
{
snd_seq_device_free
(
dev
);
return
err
;
}
try_autoload
(
ops
);
unlock_driver
(
ops
);
if
(
result
)
*
result
=
dev
;
...
...
@@ -318,16 +360,12 @@ int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry,
entry
->
init_device
==
NULL
||
entry
->
free_device
==
NULL
)
return
-
EINVAL
;
snd_seq_autoload_lock
();
ops
=
find_driver
(
id
,
1
);
if
(
ops
==
NULL
)
{
snd_seq_autoload_unlock
();
if
(
ops
==
NULL
)
return
-
ENOMEM
;
}
if
(
ops
->
driver
&
DRIVER_LOADED
)
{
pr_warn
(
"ALSA: seq: driver_register: driver '%s' already exists
\n
"
,
id
);
unlock_driver
(
ops
);
snd_seq_autoload_unlock
();
return
-
EBUSY
;
}
...
...
@@ -344,7 +382,6 @@ int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry,
mutex_unlock
(
&
ops
->
reg_mutex
);
unlock_driver
(
ops
);
snd_seq_autoload_unlock
();
return
0
;
}
...
...
@@ -554,6 +591,9 @@ static int __init alsa_seq_device_init(void)
static
void
__exit
alsa_seq_device_exit
(
void
)
{
#ifdef CONFIG_MODULES
cancel_work_sync
(
&
autoload_work
);
#endif
remove_drivers
();
#ifdef CONFIG_PROC_FS
snd_info_free_entry
(
info_entry
);
...
...
@@ -570,6 +610,7 @@ EXPORT_SYMBOL(snd_seq_device_new);
EXPORT_SYMBOL
(
snd_seq_device_register_driver
);
EXPORT_SYMBOL
(
snd_seq_device_unregister_driver
);
#ifdef CONFIG_MODULES
EXPORT_SYMBOL
(
snd_seq_autoload_init
);
EXPORT_SYMBOL
(
snd_seq_autoload_lock
);
EXPORT_SYMBOL
(
snd_seq_autoload_unlock
);
#endif
This diff is collapsed.
Click to expand it.
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录
反馈
建议
客服
返回
顶部