Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
d89d7ff9
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
d89d7ff9
编写于
12月 07, 2015
作者:
R
Rafael J. Wysocki
浏览文件
操作
浏览文件
下载
差异文件
Merge branches 'pm-sleep' and 'pm-runtime' into pm-core
上级
7b06a6d7
013c074f
5de85b9d
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
90 addition
and
7 deletion
+90
-7
drivers/base/base.h
drivers/base/base.h
+2
-0
drivers/base/dd.c
drivers/base/dd.c
+49
-1
drivers/base/power/main.c
drivers/base/power/main.c
+17
-0
drivers/base/power/power.h
drivers/base/power/power.h
+2
-0
drivers/base/power/runtime.c
drivers/base/power/runtime.c
+20
-6
未找到文件。
drivers/base/base.h
浏览文件 @
d89d7ff9
...
...
@@ -131,6 +131,8 @@ extern void device_remove_groups(struct device *dev,
extern
char
*
make_class_name
(
const
char
*
name
,
struct
kobject
*
kobj
);
extern
int
devres_release_all
(
struct
device
*
dev
);
extern
void
device_block_probing
(
void
);
extern
void
device_unblock_probing
(
void
);
/* /sys/devices directory */
extern
struct
kset
*
devices_kset
;
...
...
drivers/base/dd.c
浏览文件 @
d89d7ff9
...
...
@@ -54,6 +54,13 @@ static LIST_HEAD(deferred_probe_active_list);
static
struct
workqueue_struct
*
deferred_wq
;
static
atomic_t
deferred_trigger_count
=
ATOMIC_INIT
(
0
);
/*
* In some cases, like suspend to RAM or hibernation, It might be reasonable
* to prohibit probing of devices as it could be unsafe.
* Once defer_all_probes is true all drivers probes will be forcibly deferred.
*/
static
bool
defer_all_probes
;
/*
* deferred_probe_work_func() - Retry probing devices in the active list.
*/
...
...
@@ -171,6 +178,30 @@ static void driver_deferred_probe_trigger(void)
queue_work
(
deferred_wq
,
&
deferred_probe_work
);
}
/**
* device_block_probing() - Block/defere device's probes
*
* It will disable probing of devices and defer their probes instead.
*/
void
device_block_probing
(
void
)
{
defer_all_probes
=
true
;
/* sync with probes to avoid races. */
wait_for_device_probe
();
}
/**
* device_unblock_probing() - Unblock/enable device's probes
*
* It will restore normal behavior and trigger re-probing of deferred
* devices.
*/
void
device_unblock_probing
(
void
)
{
defer_all_probes
=
false
;
driver_deferred_probe_trigger
();
}
/**
* deferred_probe_initcall() - Enable probing of deferred devices
*
...
...
@@ -277,9 +308,20 @@ static DECLARE_WAIT_QUEUE_HEAD(probe_waitqueue);
static
int
really_probe
(
struct
device
*
dev
,
struct
device_driver
*
drv
)
{
int
ret
=
0
;
int
ret
=
-
EPROBE_DEFER
;
int
local_trigger_count
=
atomic_read
(
&
deferred_trigger_count
);
if
(
defer_all_probes
)
{
/*
* Value of defer_all_probes can be set only by
* device_defer_all_probes_enable() which, in turn, will call
* wait_for_device_probe() right after that to avoid any races.
*/
dev_dbg
(
dev
,
"Driver %s force probe deferral
\n
"
,
drv
->
name
);
driver_deferred_probe_add
(
dev
);
return
ret
;
}
atomic_inc
(
&
probe_count
);
pr_debug
(
"bus: '%s': %s: probing driver %s with device %s
\n
"
,
drv
->
bus
->
name
,
__func__
,
drv
->
name
,
dev_name
(
dev
));
...
...
@@ -340,6 +382,7 @@ static int really_probe(struct device *dev, struct device_driver *drv)
dev_set_drvdata
(
dev
,
NULL
);
if
(
dev
->
pm_domain
&&
dev
->
pm_domain
->
dismiss
)
dev
->
pm_domain
->
dismiss
(
dev
);
pm_runtime_reinit
(
dev
);
switch
(
ret
)
{
case
-
EPROBE_DEFER
:
...
...
@@ -393,6 +436,10 @@ int driver_probe_done(void)
*/
void
wait_for_device_probe
(
void
)
{
/* wait for the deferred probe workqueue to finish */
if
(
driver_deferred_probe_enable
)
flush_workqueue
(
deferred_wq
);
/* wait for the known devices to complete their probing */
wait_event
(
probe_waitqueue
,
atomic_read
(
&
probe_count
)
==
0
);
async_synchronize_full
();
...
...
@@ -695,6 +742,7 @@ static void __device_release_driver(struct device *dev)
dev_set_drvdata
(
dev
,
NULL
);
if
(
dev
->
pm_domain
&&
dev
->
pm_domain
->
dismiss
)
dev
->
pm_domain
->
dismiss
(
dev
);
pm_runtime_reinit
(
dev
);
klist_remove
(
&
dev
->
p
->
knode_driver
);
if
(
dev
->
bus
)
...
...
drivers/base/power/main.c
浏览文件 @
d89d7ff9
...
...
@@ -963,6 +963,9 @@ void dpm_complete(pm_message_t state)
}
list_splice
(
&
list
,
&
dpm_list
);
mutex_unlock
(
&
dpm_list_mtx
);
/* Allow device probing and trigger re-probing of deferred devices */
device_unblock_probing
();
trace_suspend_resume
(
TPS
(
"dpm_complete"
),
state
.
event
,
false
);
}
...
...
@@ -1624,6 +1627,20 @@ int dpm_prepare(pm_message_t state)
trace_suspend_resume
(
TPS
(
"dpm_prepare"
),
state
.
event
,
true
);
might_sleep
();
/*
* Give a chance for the known devices to complete their probes, before
* disable probing of devices. This sync point is important at least
* at boot time + hibernation restore.
*/
wait_for_device_probe
();
/*
* It is unsafe if probing of devices will happen during suspend or
* hibernation and system behavior will be unpredictable in this case.
* So, let's prohibit device's probing here and defer their probes
* instead. The normal behavior will be restored in dpm_complete().
*/
device_block_probing
();
mutex_lock
(
&
dpm_list_mtx
);
while
(
!
list_empty
(
&
dpm_list
))
{
struct
device
*
dev
=
to_device
(
dpm_list
.
next
);
...
...
drivers/base/power/power.h
浏览文件 @
d89d7ff9
...
...
@@ -18,6 +18,7 @@ static inline void pm_runtime_early_init(struct device *dev)
}
extern
void
pm_runtime_init
(
struct
device
*
dev
);
extern
void
pm_runtime_reinit
(
struct
device
*
dev
);
extern
void
pm_runtime_remove
(
struct
device
*
dev
);
struct
wake_irq
{
...
...
@@ -84,6 +85,7 @@ static inline void pm_runtime_early_init(struct device *dev)
}
static
inline
void
pm_runtime_init
(
struct
device
*
dev
)
{}
static
inline
void
pm_runtime_reinit
(
struct
device
*
dev
)
{}
static
inline
void
pm_runtime_remove
(
struct
device
*
dev
)
{}
static
inline
int
dpm_sysfs_add
(
struct
device
*
dev
)
{
return
0
;
}
...
...
drivers/base/power/runtime.c
浏览文件 @
d89d7ff9
...
...
@@ -1389,6 +1389,25 @@ void pm_runtime_init(struct device *dev)
init_waitqueue_head
(
&
dev
->
power
.
wait_queue
);
}
/**
* pm_runtime_reinit - Re-initialize runtime PM fields in given device object.
* @dev: Device object to re-initialize.
*/
void
pm_runtime_reinit
(
struct
device
*
dev
)
{
if
(
!
pm_runtime_enabled
(
dev
))
{
if
(
dev
->
power
.
runtime_status
==
RPM_ACTIVE
)
pm_runtime_set_suspended
(
dev
);
if
(
dev
->
power
.
irq_safe
)
{
spin_lock_irq
(
&
dev
->
power
.
lock
);
dev
->
power
.
irq_safe
=
0
;
spin_unlock_irq
(
&
dev
->
power
.
lock
);
if
(
dev
->
parent
)
pm_runtime_put
(
dev
->
parent
);
}
}
}
/**
* pm_runtime_remove - Prepare for removing a device from device hierarchy.
* @dev: Device object being removed from device hierarchy.
...
...
@@ -1396,12 +1415,7 @@ void pm_runtime_init(struct device *dev)
void
pm_runtime_remove
(
struct
device
*
dev
)
{
__pm_runtime_disable
(
dev
,
false
);
/* Change the status back to 'suspended' to match the initial status. */
if
(
dev
->
power
.
runtime_status
==
RPM_ACTIVE
)
pm_runtime_set_suspended
(
dev
);
if
(
dev
->
power
.
irq_safe
&&
dev
->
parent
)
pm_runtime_put
(
dev
->
parent
);
pm_runtime_reinit
(
dev
);
}
/**
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录