Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
0015afaa
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 4 年多
通知
15
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
0015afaa
编写于
12月 25, 2011
作者:
R
Rafael J. Wysocki
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'pm-runtime' into pm-for-linus
* pm-runtime: PM / Runtime: Use device PM QoS constraints (v2)
上级
b7ba68c4
00dc9ad1
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
154 addition
and
28 deletion
+154
-28
drivers/base/power/qos.c
drivers/base/power/qos.c
+16
-8
drivers/base/power/runtime.c
drivers/base/power/runtime.c
+128
-20
include/linux/pm.h
include/linux/pm.h
+2
-0
include/linux/pm_qos.h
include/linux/pm_qos.h
+3
-0
include/linux/pm_runtime.h
include/linux/pm_runtime.h
+5
-0
未找到文件。
drivers/base/power/qos.c
浏览文件 @
0015afaa
...
@@ -47,21 +47,29 @@ static DEFINE_MUTEX(dev_pm_qos_mtx);
...
@@ -47,21 +47,29 @@ static DEFINE_MUTEX(dev_pm_qos_mtx);
static
BLOCKING_NOTIFIER_HEAD
(
dev_pm_notifiers
);
static
BLOCKING_NOTIFIER_HEAD
(
dev_pm_notifiers
);
/**
/**
* dev_pm_qos_read_value - Get PM QoS constraint for a given device.
* __dev_pm_qos_read_value - Get PM QoS constraint for a given device.
* @dev: Device to get the PM QoS constraint value for.
*
* This routine must be called with dev->power.lock held.
*/
s32
__dev_pm_qos_read_value
(
struct
device
*
dev
)
{
struct
pm_qos_constraints
*
c
=
dev
->
power
.
constraints
;
return
c
?
pm_qos_read_value
(
c
)
:
0
;
}
/**
* dev_pm_qos_read_value - Get PM QoS constraint for a given device (locked).
* @dev: Device to get the PM QoS constraint value for.
* @dev: Device to get the PM QoS constraint value for.
*/
*/
s32
dev_pm_qos_read_value
(
struct
device
*
dev
)
s32
dev_pm_qos_read_value
(
struct
device
*
dev
)
{
{
struct
pm_qos_constraints
*
c
;
unsigned
long
flags
;
unsigned
long
flags
;
s32
ret
=
0
;
s32
ret
;
spin_lock_irqsave
(
&
dev
->
power
.
lock
,
flags
);
spin_lock_irqsave
(
&
dev
->
power
.
lock
,
flags
);
ret
=
__dev_pm_qos_read_value
(
dev
);
c
=
dev
->
power
.
constraints
;
if
(
c
)
ret
=
pm_qos_read_value
(
c
);
spin_unlock_irqrestore
(
&
dev
->
power
.
lock
,
flags
);
spin_unlock_irqrestore
(
&
dev
->
power
.
lock
,
flags
);
return
ret
;
return
ret
;
...
...
drivers/base/power/runtime.c
浏览文件 @
0015afaa
...
@@ -282,6 +282,47 @@ static int rpm_callback(int (*cb)(struct device *), struct device *dev)
...
@@ -282,6 +282,47 @@ static int rpm_callback(int (*cb)(struct device *), struct device *dev)
return
retval
!=
-
EACCES
?
retval
:
-
EIO
;
return
retval
!=
-
EACCES
?
retval
:
-
EIO
;
}
}
struct
rpm_qos_data
{
ktime_t
time_now
;
s64
constraint_ns
;
};
/**
* rpm_update_qos_constraint - Update a given PM QoS constraint data.
* @dev: Device whose timing data to use.
* @data: PM QoS constraint data to update.
*
* Use the suspend timing data of @dev to update PM QoS constraint data pointed
* to by @data.
*/
static
int
rpm_update_qos_constraint
(
struct
device
*
dev
,
void
*
data
)
{
struct
rpm_qos_data
*
qos
=
data
;
unsigned
long
flags
;
s64
delta_ns
;
int
ret
=
0
;
spin_lock_irqsave
(
&
dev
->
power
.
lock
,
flags
);
if
(
dev
->
power
.
max_time_suspended_ns
<
0
)
goto
out
;
delta_ns
=
dev
->
power
.
max_time_suspended_ns
-
ktime_to_ns
(
ktime_sub
(
qos
->
time_now
,
dev
->
power
.
suspend_time
));
if
(
delta_ns
<=
0
)
{
ret
=
-
EBUSY
;
goto
out
;
}
if
(
qos
->
constraint_ns
>
delta_ns
||
qos
->
constraint_ns
==
0
)
qos
->
constraint_ns
=
delta_ns
;
out:
spin_unlock_irqrestore
(
&
dev
->
power
.
lock
,
flags
);
return
ret
;
}
/**
/**
* rpm_suspend - Carry out runtime suspend of given device.
* rpm_suspend - Carry out runtime suspend of given device.
* @dev: Device to suspend.
* @dev: Device to suspend.
...
@@ -308,6 +349,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)
...
@@ -308,6 +349,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)
{
{
int
(
*
callback
)(
struct
device
*
);
int
(
*
callback
)(
struct
device
*
);
struct
device
*
parent
=
NULL
;
struct
device
*
parent
=
NULL
;
struct
rpm_qos_data
qos
;
int
retval
;
int
retval
;
trace_rpm_suspend
(
dev
,
rpmflags
);
trace_rpm_suspend
(
dev
,
rpmflags
);
...
@@ -403,8 +445,38 @@ static int rpm_suspend(struct device *dev, int rpmflags)
...
@@ -403,8 +445,38 @@ static int rpm_suspend(struct device *dev, int rpmflags)
goto
out
;
goto
out
;
}
}
qos
.
constraint_ns
=
__dev_pm_qos_read_value
(
dev
);
if
(
qos
.
constraint_ns
<
0
)
{
/* Negative constraint means "never suspend". */
retval
=
-
EPERM
;
goto
out
;
}
qos
.
constraint_ns
*=
NSEC_PER_USEC
;
qos
.
time_now
=
ktime_get
();
__update_runtime_status
(
dev
,
RPM_SUSPENDING
);
__update_runtime_status
(
dev
,
RPM_SUSPENDING
);
if
(
!
dev
->
power
.
ignore_children
)
{
if
(
dev
->
power
.
irq_safe
)
spin_unlock
(
&
dev
->
power
.
lock
);
else
spin_unlock_irq
(
&
dev
->
power
.
lock
);
retval
=
device_for_each_child
(
dev
,
&
qos
,
rpm_update_qos_constraint
);
if
(
dev
->
power
.
irq_safe
)
spin_lock
(
&
dev
->
power
.
lock
);
else
spin_lock_irq
(
&
dev
->
power
.
lock
);
if
(
retval
)
goto
fail
;
}
dev
->
power
.
suspend_time
=
qos
.
time_now
;
dev
->
power
.
max_time_suspended_ns
=
qos
.
constraint_ns
?
:
-
1
;
if
(
dev
->
pm_domain
)
if
(
dev
->
pm_domain
)
callback
=
dev
->
pm_domain
->
ops
.
runtime_suspend
;
callback
=
dev
->
pm_domain
->
ops
.
runtime_suspend
;
else
if
(
dev
->
type
&&
dev
->
type
->
pm
)
else
if
(
dev
->
type
&&
dev
->
type
->
pm
)
...
@@ -420,27 +492,9 @@ static int rpm_suspend(struct device *dev, int rpmflags)
...
@@ -420,27 +492,9 @@ static int rpm_suspend(struct device *dev, int rpmflags)
callback
=
dev
->
driver
->
pm
->
runtime_suspend
;
callback
=
dev
->
driver
->
pm
->
runtime_suspend
;
retval
=
rpm_callback
(
callback
,
dev
);
retval
=
rpm_callback
(
callback
,
dev
);
if
(
retval
)
{
if
(
retval
)
__update_runtime_status
(
dev
,
RPM_ACTIVE
);
goto
fail
;
dev
->
power
.
deferred_resume
=
false
;
if
(
retval
==
-
EAGAIN
||
retval
==
-
EBUSY
)
{
dev
->
power
.
runtime_error
=
0
;
/*
* If the callback routine failed an autosuspend, and
* if the last_busy time has been updated so that there
* is a new autosuspend expiration time, automatically
* reschedule another autosuspend.
*/
if
((
rpmflags
&
RPM_AUTO
)
&&
pm_runtime_autosuspend_expiration
(
dev
)
!=
0
)
goto
repeat
;
}
else
{
pm_runtime_cancel_pending
(
dev
);
}
wake_up_all
(
&
dev
->
power
.
wait_queue
);
goto
out
;
}
no_callback:
no_callback:
__update_runtime_status
(
dev
,
RPM_SUSPENDED
);
__update_runtime_status
(
dev
,
RPM_SUSPENDED
);
pm_runtime_deactivate_timer
(
dev
);
pm_runtime_deactivate_timer
(
dev
);
...
@@ -472,6 +526,29 @@ static int rpm_suspend(struct device *dev, int rpmflags)
...
@@ -472,6 +526,29 @@ static int rpm_suspend(struct device *dev, int rpmflags)
trace_rpm_return_int
(
dev
,
_THIS_IP_
,
retval
);
trace_rpm_return_int
(
dev
,
_THIS_IP_
,
retval
);
return
retval
;
return
retval
;
fail:
__update_runtime_status
(
dev
,
RPM_ACTIVE
);
dev
->
power
.
suspend_time
=
ktime_set
(
0
,
0
);
dev
->
power
.
max_time_suspended_ns
=
-
1
;
dev
->
power
.
deferred_resume
=
false
;
if
(
retval
==
-
EAGAIN
||
retval
==
-
EBUSY
)
{
dev
->
power
.
runtime_error
=
0
;
/*
* If the callback routine failed an autosuspend, and
* if the last_busy time has been updated so that there
* is a new autosuspend expiration time, automatically
* reschedule another autosuspend.
*/
if
((
rpmflags
&
RPM_AUTO
)
&&
pm_runtime_autosuspend_expiration
(
dev
)
!=
0
)
goto
repeat
;
}
else
{
pm_runtime_cancel_pending
(
dev
);
}
wake_up_all
(
&
dev
->
power
.
wait_queue
);
goto
out
;
}
}
/**
/**
...
@@ -626,6 +703,9 @@ static int rpm_resume(struct device *dev, int rpmflags)
...
@@ -626,6 +703,9 @@ static int rpm_resume(struct device *dev, int rpmflags)
if
(
dev
->
power
.
no_callbacks
)
if
(
dev
->
power
.
no_callbacks
)
goto
no_callback
;
/* Assume success. */
goto
no_callback
;
/* Assume success. */
dev
->
power
.
suspend_time
=
ktime_set
(
0
,
0
);
dev
->
power
.
max_time_suspended_ns
=
-
1
;
__update_runtime_status
(
dev
,
RPM_RESUMING
);
__update_runtime_status
(
dev
,
RPM_RESUMING
);
if
(
dev
->
pm_domain
)
if
(
dev
->
pm_domain
)
...
@@ -1288,6 +1368,9 @@ void pm_runtime_init(struct device *dev)
...
@@ -1288,6 +1368,9 @@ void pm_runtime_init(struct device *dev)
setup_timer
(
&
dev
->
power
.
suspend_timer
,
pm_suspend_timer_fn
,
setup_timer
(
&
dev
->
power
.
suspend_timer
,
pm_suspend_timer_fn
,
(
unsigned
long
)
dev
);
(
unsigned
long
)
dev
);
dev
->
power
.
suspend_time
=
ktime_set
(
0
,
0
);
dev
->
power
.
max_time_suspended_ns
=
-
1
;
init_waitqueue_head
(
&
dev
->
power
.
wait_queue
);
init_waitqueue_head
(
&
dev
->
power
.
wait_queue
);
}
}
...
@@ -1305,3 +1388,28 @@ void pm_runtime_remove(struct device *dev)
...
@@ -1305,3 +1388,28 @@ void pm_runtime_remove(struct device *dev)
if
(
dev
->
power
.
irq_safe
&&
dev
->
parent
)
if
(
dev
->
power
.
irq_safe
&&
dev
->
parent
)
pm_runtime_put_sync
(
dev
->
parent
);
pm_runtime_put_sync
(
dev
->
parent
);
}
}
/**
* pm_runtime_update_max_time_suspended - Update device's suspend time data.
* @dev: Device to handle.
* @delta_ns: Value to subtract from the device's max_time_suspended_ns field.
*
* Update the device's power.max_time_suspended_ns field by subtracting
* @delta_ns from it. The resulting value of power.max_time_suspended_ns is
* never negative.
*/
void
pm_runtime_update_max_time_suspended
(
struct
device
*
dev
,
s64
delta_ns
)
{
unsigned
long
flags
;
spin_lock_irqsave
(
&
dev
->
power
.
lock
,
flags
);
if
(
delta_ns
>
0
&&
dev
->
power
.
max_time_suspended_ns
>
0
)
{
if
(
dev
->
power
.
max_time_suspended_ns
>
delta_ns
)
dev
->
power
.
max_time_suspended_ns
-=
delta_ns
;
else
dev
->
power
.
max_time_suspended_ns
=
0
;
}
spin_unlock_irqrestore
(
&
dev
->
power
.
lock
,
flags
);
}
include/linux/pm.h
浏览文件 @
0015afaa
...
@@ -508,6 +508,8 @@ struct dev_pm_info {
...
@@ -508,6 +508,8 @@ struct dev_pm_info {
unsigned
long
active_jiffies
;
unsigned
long
active_jiffies
;
unsigned
long
suspended_jiffies
;
unsigned
long
suspended_jiffies
;
unsigned
long
accounting_timestamp
;
unsigned
long
accounting_timestamp
;
ktime_t
suspend_time
;
s64
max_time_suspended_ns
;
#endif
#endif
struct
pm_subsys_data
*
subsys_data
;
/* Owned by the subsystem. */
struct
pm_subsys_data
*
subsys_data
;
/* Owned by the subsystem. */
struct
pm_qos_constraints
*
constraints
;
struct
pm_qos_constraints
*
constraints
;
...
...
include/linux/pm_qos.h
浏览文件 @
0015afaa
...
@@ -78,6 +78,7 @@ int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier);
...
@@ -78,6 +78,7 @@ int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier);
int
pm_qos_request_active
(
struct
pm_qos_request
*
req
);
int
pm_qos_request_active
(
struct
pm_qos_request
*
req
);
s32
pm_qos_read_value
(
struct
pm_qos_constraints
*
c
);
s32
pm_qos_read_value
(
struct
pm_qos_constraints
*
c
);
s32
__dev_pm_qos_read_value
(
struct
device
*
dev
);
s32
dev_pm_qos_read_value
(
struct
device
*
dev
);
s32
dev_pm_qos_read_value
(
struct
device
*
dev
);
int
dev_pm_qos_add_request
(
struct
device
*
dev
,
struct
dev_pm_qos_request
*
req
,
int
dev_pm_qos_add_request
(
struct
device
*
dev
,
struct
dev_pm_qos_request
*
req
,
s32
value
);
s32
value
);
...
@@ -119,6 +120,8 @@ static inline int pm_qos_request_active(struct pm_qos_request *req)
...
@@ -119,6 +120,8 @@ static inline int pm_qos_request_active(struct pm_qos_request *req)
static
inline
s32
pm_qos_read_value
(
struct
pm_qos_constraints
*
c
)
static
inline
s32
pm_qos_read_value
(
struct
pm_qos_constraints
*
c
)
{
return
0
;
}
{
return
0
;
}
static
inline
s32
__dev_pm_qos_read_value
(
struct
device
*
dev
)
{
return
0
;
}
static
inline
s32
dev_pm_qos_read_value
(
struct
device
*
dev
)
static
inline
s32
dev_pm_qos_read_value
(
struct
device
*
dev
)
{
return
0
;
}
{
return
0
;
}
static
inline
int
dev_pm_qos_add_request
(
struct
device
*
dev
,
static
inline
int
dev_pm_qos_add_request
(
struct
device
*
dev
,
...
...
include/linux/pm_runtime.h
浏览文件 @
0015afaa
...
@@ -45,6 +45,8 @@ extern void pm_runtime_irq_safe(struct device *dev);
...
@@ -45,6 +45,8 @@ extern void pm_runtime_irq_safe(struct device *dev);
extern
void
__pm_runtime_use_autosuspend
(
struct
device
*
dev
,
bool
use
);
extern
void
__pm_runtime_use_autosuspend
(
struct
device
*
dev
,
bool
use
);
extern
void
pm_runtime_set_autosuspend_delay
(
struct
device
*
dev
,
int
delay
);
extern
void
pm_runtime_set_autosuspend_delay
(
struct
device
*
dev
,
int
delay
);
extern
unsigned
long
pm_runtime_autosuspend_expiration
(
struct
device
*
dev
);
extern
unsigned
long
pm_runtime_autosuspend_expiration
(
struct
device
*
dev
);
extern
void
pm_runtime_update_max_time_suspended
(
struct
device
*
dev
,
s64
delta_ns
);
static
inline
bool
pm_children_suspended
(
struct
device
*
dev
)
static
inline
bool
pm_children_suspended
(
struct
device
*
dev
)
{
{
...
@@ -148,6 +150,9 @@ static inline void pm_runtime_set_autosuspend_delay(struct device *dev,
...
@@ -148,6 +150,9 @@ static inline void pm_runtime_set_autosuspend_delay(struct device *dev,
static
inline
unsigned
long
pm_runtime_autosuspend_expiration
(
static
inline
unsigned
long
pm_runtime_autosuspend_expiration
(
struct
device
*
dev
)
{
return
0
;
}
struct
device
*
dev
)
{
return
0
;
}
static
inline
void
pm_runtime_update_max_time_suspended
(
struct
device
*
dev
,
s64
delta_ns
)
{}
#endif
/* !CONFIG_PM_RUNTIME */
#endif
/* !CONFIG_PM_RUNTIME */
static
inline
int
pm_runtime_idle
(
struct
device
*
dev
)
static
inline
int
pm_runtime_idle
(
struct
device
*
dev
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录