Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
8a78cf70
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看板
提交
8a78cf70
编写于
1月 29, 2013
作者:
R
Rafael J. Wysocki
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'acpi-pm' into acpi-cleanup
The following commits depend on the 'acpi-pm' material.
上级
09212fdd
65ab96f6
变更
23
展开全部
隐藏空白更改
内联
并排
Showing
23 changed file
with
1313 addition
and
897 deletion
+1313
-897
Documentation/ABI/testing/sysfs-devices-power_resources_D0
Documentation/ABI/testing/sysfs-devices-power_resources_D0
+13
-0
Documentation/ABI/testing/sysfs-devices-power_resources_D1
Documentation/ABI/testing/sysfs-devices-power_resources_D1
+14
-0
Documentation/ABI/testing/sysfs-devices-power_resources_D2
Documentation/ABI/testing/sysfs-devices-power_resources_D2
+14
-0
Documentation/ABI/testing/sysfs-devices-power_resources_D3hot
...mentation/ABI/testing/sysfs-devices-power_resources_D3hot
+14
-0
Documentation/ABI/testing/sysfs-devices-power_state
Documentation/ABI/testing/sysfs-devices-power_state
+20
-0
Documentation/ABI/testing/sysfs-devices-real_power_state
Documentation/ABI/testing/sysfs-devices-real_power_state
+23
-0
Documentation/ABI/testing/sysfs-devices-resource_in_use
Documentation/ABI/testing/sysfs-devices-resource_in_use
+12
-0
drivers/acpi/bus.c
drivers/acpi/bus.c
+0
-270
drivers/acpi/device_pm.c
drivers/acpi/device_pm.c
+341
-1
drivers/acpi/internal.h
drivers/acpi/internal.h
+19
-1
drivers/acpi/power.c
drivers/acpi/power.c
+395
-335
drivers/acpi/proc.c
drivers/acpi/proc.c
+5
-4
drivers/acpi/scan.c
drivers/acpi/scan.c
+241
-216
drivers/acpi/sleep.c
drivers/acpi/sleep.c
+53
-36
drivers/acpi/sleep.h
drivers/acpi/sleep.h
+2
-0
drivers/ata/libata-acpi.c
drivers/ata/libata-acpi.c
+4
-14
drivers/pci/pci-acpi.c
drivers/pci/pci-acpi.c
+0
-2
fs/sysfs/group.c
fs/sysfs/group.c
+42
-0
fs/sysfs/symlink.c
fs/sysfs/symlink.c
+32
-13
fs/sysfs/sysfs.h
fs/sysfs/sysfs.h
+2
-0
include/acpi/acpi_bus.h
include/acpi/acpi_bus.h
+50
-4
include/linux/acpi.h
include/linux/acpi.h
+1
-1
include/linux/sysfs.h
include/linux/sysfs.h
+16
-0
未找到文件。
Documentation/ABI/testing/sysfs-devices-power_resources_D0
0 → 100644
浏览文件 @
8a78cf70
What: /sys/devices/.../power_resources_D0/
Date: January 2013
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Description:
The /sys/devices/.../power_resources_D0/ directory is only
present for device objects representing ACPI device nodes that
use ACPI power resources for power management.
If present, it contains symbolic links to device directories
representing ACPI power resources that need to be turned on for
the given device node to be in ACPI power state D0. The names
of the links are the same as the names of the directories they
point to.
Documentation/ABI/testing/sysfs-devices-power_resources_D1
0 → 100644
浏览文件 @
8a78cf70
What: /sys/devices/.../power_resources_D1/
Date: January 2013
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Description:
The /sys/devices/.../power_resources_D1/ directory is only
present for device objects representing ACPI device nodes that
use ACPI power resources for power management and support ACPI
power state D1.
If present, it contains symbolic links to device directories
representing ACPI power resources that need to be turned on for
the given device node to be in ACPI power state D1. The names
of the links are the same as the names of the directories they
point to.
Documentation/ABI/testing/sysfs-devices-power_resources_D2
0 → 100644
浏览文件 @
8a78cf70
What: /sys/devices/.../power_resources_D2/
Date: January 2013
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Description:
The /sys/devices/.../power_resources_D2/ directory is only
present for device objects representing ACPI device nodes that
use ACPI power resources for power management and support ACPI
power state D2.
If present, it contains symbolic links to device directories
representing ACPI power resources that need to be turned on for
the given device node to be in ACPI power state D2. The names
of the links are the same as the names of the directories they
point to.
Documentation/ABI/testing/sysfs-devices-power_resources_D3hot
0 → 100644
浏览文件 @
8a78cf70
What: /sys/devices/.../power_resources_D3hot/
Date: January 2013
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Description:
The /sys/devices/.../power_resources_D3hot/ directory is only
present for device objects representing ACPI device nodes that
use ACPI power resources for power management and support ACPI
power state D3hot.
If present, it contains symbolic links to device directories
representing ACPI power resources that need to be turned on for
the given device node to be in ACPI power state D3hot. The
names of the links are the same as the names of the directories
they point to.
Documentation/ABI/testing/sysfs-devices-power_state
0 → 100644
浏览文件 @
8a78cf70
What: /sys/devices/.../power_state
Date: January 2013
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Description:
The /sys/devices/.../power_state attribute is only present for
device objects representing ACPI device nodes that provide power
management methods.
If present, it contains a string representing the current ACPI
power state of the given device node. Its possible values,
"D0", "D1", "D2", "D3hot", and "D3cold", reflect the power state
names defined by the ACPI specification (ACPI 4 and above).
If the device node uses shared ACPI power resources, this state
determines a list of power resources required not to be turned
off. However, some power resources needed by the device node in
higher-power (lower-number) states may also be ON because of
some other devices using them at the moment.
This attribute is read-only.
Documentation/ABI/testing/sysfs-devices-real_power_state
0 → 100644
浏览文件 @
8a78cf70
What: /sys/devices/.../real_power_state
Date: January 2013
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Description:
The /sys/devices/.../real_power_state attribute is only present
for device objects representing ACPI device nodes that provide
power management methods and use ACPI power resources for power
management.
If present, it contains a string representing the real ACPI
power state of the given device node as returned by the _PSC
control method or inferred from the configuration of power
resources. Its possible values, "D0", "D1", "D2", "D3hot", and
"D3cold", reflect the power state names defined by the ACPI
specification (ACPI 4 and above).
In some situations the value of this attribute may be different
from the value of the /sys/devices/.../power_state attribute for
the same device object. If that happens, some shared power
resources used by the device node are only ON because of some
other devices using them at the moment.
This attribute is read-only.
Documentation/ABI/testing/sysfs-devices-resource_in_use
0 → 100644
浏览文件 @
8a78cf70
What: /sys/devices/.../resource_in_use
Date: January 2013
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Description:
The /sys/devices/.../resource_in_use attribute is only present
for device objects representing ACPI power resources.
If present, it contains a number (0 or 1) representing the
current status of the given power resource (0 means that the
resource is not in use and therefore it has been turned off).
This attribute is read-only.
drivers/acpi/bus.c
浏览文件 @
8a78cf70
...
...
@@ -178,276 +178,6 @@ int acpi_bus_get_private_data(acpi_handle handle, void **data)
}
EXPORT_SYMBOL
(
acpi_bus_get_private_data
);
/* --------------------------------------------------------------------------
Power Management
-------------------------------------------------------------------------- */
static
const
char
*
state_string
(
int
state
)
{
switch
(
state
)
{
case
ACPI_STATE_D0
:
return
"D0"
;
case
ACPI_STATE_D1
:
return
"D1"
;
case
ACPI_STATE_D2
:
return
"D2"
;
case
ACPI_STATE_D3_HOT
:
return
"D3hot"
;
case
ACPI_STATE_D3_COLD
:
return
"D3"
;
default:
return
"(unknown)"
;
}
}
static
int
__acpi_bus_get_power
(
struct
acpi_device
*
device
,
int
*
state
)
{
int
result
=
ACPI_STATE_UNKNOWN
;
if
(
!
device
||
!
state
)
return
-
EINVAL
;
if
(
!
device
->
flags
.
power_manageable
)
{
/* TBD: Non-recursive algorithm for walking up hierarchy. */
*
state
=
device
->
parent
?
device
->
parent
->
power
.
state
:
ACPI_STATE_D0
;
goto
out
;
}
/*
* Get the device's power state either directly (via _PSC) or
* indirectly (via power resources).
*/
if
(
device
->
power
.
flags
.
explicit_get
)
{
unsigned
long
long
psc
;
acpi_status
status
=
acpi_evaluate_integer
(
device
->
handle
,
"_PSC"
,
NULL
,
&
psc
);
if
(
ACPI_FAILURE
(
status
))
return
-
ENODEV
;
result
=
psc
;
}
/* The test below covers ACPI_STATE_UNKNOWN too. */
if
(
result
<=
ACPI_STATE_D2
)
{
;
/* Do nothing. */
}
else
if
(
device
->
power
.
flags
.
power_resources
)
{
int
error
=
acpi_power_get_inferred_state
(
device
,
&
result
);
if
(
error
)
return
error
;
}
else
if
(
result
==
ACPI_STATE_D3_HOT
)
{
result
=
ACPI_STATE_D3
;
}
/*
* If we were unsure about the device parent's power state up to this
* point, the fact that the device is in D0 implies that the parent has
* to be in D0 too.
*/
if
(
device
->
parent
&&
device
->
parent
->
power
.
state
==
ACPI_STATE_UNKNOWN
&&
result
==
ACPI_STATE_D0
)
device
->
parent
->
power
.
state
=
ACPI_STATE_D0
;
*
state
=
result
;
out:
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Device [%s] power state is %s
\n
"
,
device
->
pnp
.
bus_id
,
state_string
(
*
state
)));
return
0
;
}
/**
* acpi_device_set_power - Set power state of an ACPI device.
* @device: Device to set the power state of.
* @state: New power state to set.
*
* Callers must ensure that the device is power manageable before using this
* function.
*/
int
acpi_device_set_power
(
struct
acpi_device
*
device
,
int
state
)
{
int
result
=
0
;
acpi_status
status
=
AE_OK
;
char
object_name
[
5
]
=
{
'_'
,
'P'
,
'S'
,
'0'
+
state
,
'\0'
};
if
(
!
device
||
(
state
<
ACPI_STATE_D0
)
||
(
state
>
ACPI_STATE_D3_COLD
))
return
-
EINVAL
;
/* Make sure this is a valid target state */
if
(
state
==
device
->
power
.
state
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Device is already at %s
\n
"
,
state_string
(
state
)));
return
0
;
}
if
(
!
device
->
power
.
states
[
state
].
flags
.
valid
)
{
printk
(
KERN_WARNING
PREFIX
"Device does not support %s
\n
"
,
state_string
(
state
));
return
-
ENODEV
;
}
if
(
device
->
parent
&&
(
state
<
device
->
parent
->
power
.
state
))
{
printk
(
KERN_WARNING
PREFIX
"Cannot set device to a higher-powered"
" state than parent
\n
"
);
return
-
ENODEV
;
}
/* For D3cold we should execute _PS3, not _PS4. */
if
(
state
==
ACPI_STATE_D3_COLD
)
object_name
[
3
]
=
'3'
;
/*
* Transition Power
* ----------------
* On transitions to a high-powered state we first apply power (via
* power resources) then evalute _PSx. Conversly for transitions to
* a lower-powered state.
*/
if
(
state
<
device
->
power
.
state
)
{
if
(
device
->
power
.
state
>=
ACPI_STATE_D3_HOT
&&
state
!=
ACPI_STATE_D0
)
{
printk
(
KERN_WARNING
PREFIX
"Cannot transition to non-D0 state from D3
\n
"
);
return
-
ENODEV
;
}
if
(
device
->
power
.
flags
.
power_resources
)
{
result
=
acpi_power_transition
(
device
,
state
);
if
(
result
)
goto
end
;
}
if
(
device
->
power
.
states
[
state
].
flags
.
explicit_set
)
{
status
=
acpi_evaluate_object
(
device
->
handle
,
object_name
,
NULL
,
NULL
);
if
(
ACPI_FAILURE
(
status
))
{
result
=
-
ENODEV
;
goto
end
;
}
}
}
else
{
if
(
device
->
power
.
states
[
state
].
flags
.
explicit_set
)
{
status
=
acpi_evaluate_object
(
device
->
handle
,
object_name
,
NULL
,
NULL
);
if
(
ACPI_FAILURE
(
status
))
{
result
=
-
ENODEV
;
goto
end
;
}
}
if
(
device
->
power
.
flags
.
power_resources
)
{
result
=
acpi_power_transition
(
device
,
state
);
if
(
result
)
goto
end
;
}
}
end:
if
(
result
)
printk
(
KERN_WARNING
PREFIX
"Device [%s] failed to transition to %s
\n
"
,
device
->
pnp
.
bus_id
,
state_string
(
state
));
else
{
device
->
power
.
state
=
state
;
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Device [%s] transitioned to %s
\n
"
,
device
->
pnp
.
bus_id
,
state_string
(
state
)));
}
return
result
;
}
EXPORT_SYMBOL
(
acpi_device_set_power
);
int
acpi_bus_set_power
(
acpi_handle
handle
,
int
state
)
{
struct
acpi_device
*
device
;
int
result
;
result
=
acpi_bus_get_device
(
handle
,
&
device
);
if
(
result
)
return
result
;
if
(
!
device
->
flags
.
power_manageable
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Device [%s] is not power manageable
\n
"
,
dev_name
(
&
device
->
dev
)));
return
-
ENODEV
;
}
return
acpi_device_set_power
(
device
,
state
);
}
EXPORT_SYMBOL
(
acpi_bus_set_power
);
int
acpi_bus_init_power
(
struct
acpi_device
*
device
)
{
int
state
;
int
result
;
if
(
!
device
)
return
-
EINVAL
;
device
->
power
.
state
=
ACPI_STATE_UNKNOWN
;
result
=
__acpi_bus_get_power
(
device
,
&
state
);
if
(
result
)
return
result
;
if
(
device
->
power
.
flags
.
power_resources
)
result
=
acpi_power_on_resources
(
device
,
state
);
if
(
!
result
)
device
->
power
.
state
=
state
;
return
result
;
}
int
acpi_bus_update_power
(
acpi_handle
handle
,
int
*
state_p
)
{
struct
acpi_device
*
device
;
int
state
;
int
result
;
result
=
acpi_bus_get_device
(
handle
,
&
device
);
if
(
result
)
return
result
;
result
=
__acpi_bus_get_power
(
device
,
&
state
);
if
(
result
)
return
result
;
result
=
acpi_device_set_power
(
device
,
state
);
if
(
!
result
&&
state_p
)
*
state_p
=
state
;
return
result
;
}
EXPORT_SYMBOL_GPL
(
acpi_bus_update_power
);
bool
acpi_bus_power_manageable
(
acpi_handle
handle
)
{
struct
acpi_device
*
device
;
int
result
;
result
=
acpi_bus_get_device
(
handle
,
&
device
);
return
result
?
false
:
device
->
flags
.
power_manageable
;
}
EXPORT_SYMBOL
(
acpi_bus_power_manageable
);
bool
acpi_bus_can_wakeup
(
acpi_handle
handle
)
{
struct
acpi_device
*
device
;
int
result
;
result
=
acpi_bus_get_device
(
handle
,
&
device
);
return
result
?
false
:
device
->
wakeup
.
flags
.
valid
;
}
EXPORT_SYMBOL
(
acpi_bus_can_wakeup
);
static
void
acpi_print_osc_error
(
acpi_handle
handle
,
struct
acpi_osc_context
*
context
,
char
*
error
)
{
...
...
drivers/acpi/device_pm.c
浏览文件 @
8a78cf70
...
...
@@ -30,6 +30,12 @@
#include <acpi/acpi.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
#include "internal.h"
#define _COMPONENT ACPI_POWER_COMPONENT
ACPI_MODULE_NAME
(
"device_pm"
);
static
DEFINE_MUTEX
(
acpi_pm_notifier_lock
);
...
...
@@ -93,6 +99,284 @@ acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
return
status
;
}
/**
* acpi_power_state_string - String representation of ACPI device power state.
* @state: ACPI device power state to return the string representation of.
*/
const
char
*
acpi_power_state_string
(
int
state
)
{
switch
(
state
)
{
case
ACPI_STATE_D0
:
return
"D0"
;
case
ACPI_STATE_D1
:
return
"D1"
;
case
ACPI_STATE_D2
:
return
"D2"
;
case
ACPI_STATE_D3_HOT
:
return
"D3hot"
;
case
ACPI_STATE_D3_COLD
:
return
"D3cold"
;
default:
return
"(unknown)"
;
}
}
/**
* acpi_device_get_power - Get power state of an ACPI device.
* @device: Device to get the power state of.
* @state: Place to store the power state of the device.
*
* This function does not update the device's power.state field, but it may
* update its parent's power.state field (when the parent's power state is
* unknown and the device's power state turns out to be D0).
*/
int
acpi_device_get_power
(
struct
acpi_device
*
device
,
int
*
state
)
{
int
result
=
ACPI_STATE_UNKNOWN
;
if
(
!
device
||
!
state
)
return
-
EINVAL
;
if
(
!
device
->
flags
.
power_manageable
)
{
/* TBD: Non-recursive algorithm for walking up hierarchy. */
*
state
=
device
->
parent
?
device
->
parent
->
power
.
state
:
ACPI_STATE_D0
;
goto
out
;
}
/*
* Get the device's power state either directly (via _PSC) or
* indirectly (via power resources).
*/
if
(
device
->
power
.
flags
.
explicit_get
)
{
unsigned
long
long
psc
;
acpi_status
status
=
acpi_evaluate_integer
(
device
->
handle
,
"_PSC"
,
NULL
,
&
psc
);
if
(
ACPI_FAILURE
(
status
))
return
-
ENODEV
;
result
=
psc
;
}
/* The test below covers ACPI_STATE_UNKNOWN too. */
if
(
result
<=
ACPI_STATE_D2
)
{
;
/* Do nothing. */
}
else
if
(
device
->
power
.
flags
.
power_resources
)
{
int
error
=
acpi_power_get_inferred_state
(
device
,
&
result
);
if
(
error
)
return
error
;
}
else
if
(
result
==
ACPI_STATE_D3_HOT
)
{
result
=
ACPI_STATE_D3
;
}
/*
* If we were unsure about the device parent's power state up to this
* point, the fact that the device is in D0 implies that the parent has
* to be in D0 too.
*/
if
(
device
->
parent
&&
device
->
parent
->
power
.
state
==
ACPI_STATE_UNKNOWN
&&
result
==
ACPI_STATE_D0
)
device
->
parent
->
power
.
state
=
ACPI_STATE_D0
;
*
state
=
result
;
out:
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Device [%s] power state is %s
\n
"
,
device
->
pnp
.
bus_id
,
acpi_power_state_string
(
*
state
)));
return
0
;
}
static
int
acpi_dev_pm_explicit_set
(
struct
acpi_device
*
adev
,
int
state
)
{
if
(
adev
->
power
.
states
[
state
].
flags
.
explicit_set
)
{
char
method
[
5
]
=
{
'_'
,
'P'
,
'S'
,
'0'
+
state
,
'\0'
};
acpi_status
status
;
status
=
acpi_evaluate_object
(
adev
->
handle
,
method
,
NULL
,
NULL
);
if
(
ACPI_FAILURE
(
status
))
return
-
ENODEV
;
}
return
0
;
}
/**
* acpi_device_set_power - Set power state of an ACPI device.
* @device: Device to set the power state of.
* @state: New power state to set.
*
* Callers must ensure that the device is power manageable before using this
* function.
*/
int
acpi_device_set_power
(
struct
acpi_device
*
device
,
int
state
)
{
int
result
=
0
;
bool
cut_power
=
false
;
if
(
!
device
||
(
state
<
ACPI_STATE_D0
)
||
(
state
>
ACPI_STATE_D3_COLD
))
return
-
EINVAL
;
/* Make sure this is a valid target state */
if
(
state
==
device
->
power
.
state
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Device is already at %s
\n
"
,
acpi_power_state_string
(
state
)));
return
0
;
}
if
(
!
device
->
power
.
states
[
state
].
flags
.
valid
)
{
printk
(
KERN_WARNING
PREFIX
"Device does not support %s
\n
"
,
acpi_power_state_string
(
state
));
return
-
ENODEV
;
}
if
(
device
->
parent
&&
(
state
<
device
->
parent
->
power
.
state
))
{
printk
(
KERN_WARNING
PREFIX
"Cannot set device to a higher-powered"
" state than parent
\n
"
);
return
-
ENODEV
;
}
/* For D3cold we should first transition into D3hot. */
if
(
state
==
ACPI_STATE_D3_COLD
&&
device
->
power
.
states
[
ACPI_STATE_D3_COLD
].
flags
.
os_accessible
)
{
state
=
ACPI_STATE_D3_HOT
;
cut_power
=
true
;
}
if
(
state
<
device
->
power
.
state
&&
state
!=
ACPI_STATE_D0
&&
device
->
power
.
state
>=
ACPI_STATE_D3_HOT
)
{
printk
(
KERN_WARNING
PREFIX
"Cannot transition to non-D0 state from D3
\n
"
);
return
-
ENODEV
;
}
/*
* Transition Power
* ----------------
* In accordance with the ACPI specification first apply power (via
* power resources) and then evalute _PSx.
*/
if
(
device
->
power
.
flags
.
power_resources
)
{
result
=
acpi_power_transition
(
device
,
state
);
if
(
result
)
goto
end
;
}
result
=
acpi_dev_pm_explicit_set
(
device
,
state
);
if
(
result
)
goto
end
;
if
(
cut_power
)
{
device
->
power
.
state
=
state
;
state
=
ACPI_STATE_D3_COLD
;
result
=
acpi_power_transition
(
device
,
state
);
}
end:
if
(
result
)
{
printk
(
KERN_WARNING
PREFIX
"Device [%s] failed to transition to %s
\n
"
,
device
->
pnp
.
bus_id
,
acpi_power_state_string
(
state
));
}
else
{
device
->
power
.
state
=
state
;
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Device [%s] transitioned to %s
\n
"
,
device
->
pnp
.
bus_id
,
acpi_power_state_string
(
state
)));
}
return
result
;
}
EXPORT_SYMBOL
(
acpi_device_set_power
);
int
acpi_bus_set_power
(
acpi_handle
handle
,
int
state
)
{
struct
acpi_device
*
device
;
int
result
;
result
=
acpi_bus_get_device
(
handle
,
&
device
);
if
(
result
)
return
result
;
if
(
!
device
->
flags
.
power_manageable
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Device [%s] is not power manageable
\n
"
,
dev_name
(
&
device
->
dev
)));
return
-
ENODEV
;
}
return
acpi_device_set_power
(
device
,
state
);
}
EXPORT_SYMBOL
(
acpi_bus_set_power
);
int
acpi_bus_init_power
(
struct
acpi_device
*
device
)
{
int
state
;
int
result
;
if
(
!
device
)
return
-
EINVAL
;
device
->
power
.
state
=
ACPI_STATE_UNKNOWN
;
result
=
acpi_device_get_power
(
device
,
&
state
);
if
(
result
)
return
result
;
if
(
state
<
ACPI_STATE_D3_COLD
&&
device
->
power
.
flags
.
power_resources
)
{
result
=
acpi_power_on_resources
(
device
,
state
);
if
(
result
)
return
result
;
result
=
acpi_dev_pm_explicit_set
(
device
,
state
);
if
(
result
)
return
result
;
}
device
->
power
.
state
=
state
;
return
0
;
}
int
acpi_bus_update_power
(
acpi_handle
handle
,
int
*
state_p
)
{
struct
acpi_device
*
device
;
int
state
;
int
result
;
result
=
acpi_bus_get_device
(
handle
,
&
device
);
if
(
result
)
return
result
;
result
=
acpi_device_get_power
(
device
,
&
state
);
if
(
result
)
return
result
;
result
=
acpi_device_set_power
(
device
,
state
);
if
(
!
result
&&
state_p
)
*
state_p
=
state
;
return
result
;
}
EXPORT_SYMBOL_GPL
(
acpi_bus_update_power
);
bool
acpi_bus_power_manageable
(
acpi_handle
handle
)
{
struct
acpi_device
*
device
;
int
result
;
result
=
acpi_bus_get_device
(
handle
,
&
device
);
return
result
?
false
:
device
->
flags
.
power_manageable
;
}
EXPORT_SYMBOL
(
acpi_bus_power_manageable
);
bool
acpi_bus_can_wakeup
(
acpi_handle
handle
)
{
struct
acpi_device
*
device
;
int
result
;
result
=
acpi_bus_get_device
(
handle
,
&
device
);
return
result
?
false
:
device
->
wakeup
.
flags
.
valid
;
}
EXPORT_SYMBOL
(
acpi_bus_can_wakeup
);
/**
* acpi_device_power_state - Get preferred power state of ACPI device.
* @dev: Device whose preferred target power state to return.
...
...
@@ -304,7 +588,7 @@ static inline void acpi_wakeup_device(acpi_handle handle, u32 event,
void
*
context
)
{}
#endif
/* CONFIG_PM_RUNTIME */
#ifdef CONFIG_PM_SLEEP
#ifdef CONFIG_PM_SLEEP
/**
* __acpi_device_sleep_wake - Enable or disable device to wake up the system.
* @dev: Device to enable/desible to wake up the system.
...
...
@@ -665,3 +949,59 @@ void acpi_dev_pm_detach(struct device *dev, bool power_off)
}
}
EXPORT_SYMBOL_GPL
(
acpi_dev_pm_detach
);
/**
* acpi_dev_pm_add_dependent - Add physical device depending for PM.
* @handle: Handle of ACPI device node.
* @depdev: Device depending on that node for PM.
*/
void
acpi_dev_pm_add_dependent
(
acpi_handle
handle
,
struct
device
*
depdev
)
{
struct
acpi_device_physical_node
*
dep
;
struct
acpi_device
*
adev
;
if
(
!
depdev
||
acpi_bus_get_device
(
handle
,
&
adev
))
return
;
mutex_lock
(
&
adev
->
physical_node_lock
);
list_for_each_entry
(
dep
,
&
adev
->
power_dependent
,
node
)
if
(
dep
->
dev
==
depdev
)
goto
out
;
dep
=
kzalloc
(
sizeof
(
*
dep
),
GFP_KERNEL
);
if
(
dep
)
{
dep
->
dev
=
depdev
;
list_add_tail
(
&
dep
->
node
,
&
adev
->
power_dependent
);
}
out:
mutex_unlock
(
&
adev
->
physical_node_lock
);
}
EXPORT_SYMBOL_GPL
(
acpi_dev_pm_add_dependent
);
/**
* acpi_dev_pm_remove_dependent - Remove physical device depending for PM.
* @handle: Handle of ACPI device node.
* @depdev: Device depending on that node for PM.
*/
void
acpi_dev_pm_remove_dependent
(
acpi_handle
handle
,
struct
device
*
depdev
)
{
struct
acpi_device_physical_node
*
dep
;
struct
acpi_device
*
adev
;
if
(
!
depdev
||
acpi_bus_get_device
(
handle
,
&
adev
))
return
;
mutex_lock
(
&
adev
->
physical_node_lock
);
list_for_each_entry
(
dep
,
&
adev
->
power_dependent
,
node
)
if
(
dep
->
dev
==
depdev
)
{
list_del
(
&
dep
->
node
);
kfree
(
dep
);
break
;
}
mutex_unlock
(
&
adev
->
physical_node_lock
);
}
EXPORT_SYMBOL_GPL
(
acpi_dev_pm_remove_dependent
);
drivers/acpi/internal.h
浏览文件 @
8a78cf70
...
...
@@ -34,16 +34,34 @@ int acpi_debugfs_init(void);
static
inline
void
acpi_debugfs_init
(
void
)
{
return
;
}
#endif
/* --------------------------------------------------------------------------
Device Node Initialization / Removal
-------------------------------------------------------------------------- */
#define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \
ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING)
int
acpi_device_add
(
struct
acpi_device
*
device
,
void
(
*
release
)(
struct
device
*
));
void
acpi_init_device_object
(
struct
acpi_device
*
device
,
acpi_handle
handle
,
int
type
,
unsigned
long
long
sta
);
void
acpi_device_add_finalize
(
struct
acpi_device
*
device
);
void
acpi_free_ids
(
struct
acpi_device
*
device
);
/* --------------------------------------------------------------------------
Power Resource
-------------------------------------------------------------------------- */
int
acpi_power_init
(
void
);
void
acpi_power_resources_list_free
(
struct
list_head
*
list
);
int
acpi_extract_power_resources
(
union
acpi_object
*
package
,
unsigned
int
start
,
struct
list_head
*
list
);
int
acpi_add_power_resource
(
acpi_handle
handle
);
void
acpi_power_add_remove_device
(
struct
acpi_device
*
adev
,
bool
add
);
int
acpi_power_min_system_level
(
struct
list_head
*
list
);
int
acpi_device_sleep_wake
(
struct
acpi_device
*
dev
,
int
enable
,
int
sleep_state
,
int
dev_state
);
int
acpi_power_get_inferred_state
(
struct
acpi_device
*
device
,
int
*
state
);
int
acpi_power_on_resources
(
struct
acpi_device
*
device
,
int
state
);
int
acpi_power_transition
(
struct
acpi_device
*
device
,
int
state
);
int
acpi_bus_init_power
(
struct
acpi_device
*
device
);
int
acpi_wakeup_device_init
(
void
);
void
acpi_early_processor_set_pdc
(
void
);
...
...
drivers/acpi/power.c
浏览文件 @
8a78cf70
此差异已折叠。
点击以展开。
drivers/acpi/proc.c
浏览文件 @
8a78cf70
...
...
@@ -311,11 +311,12 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
dev
->
pnp
.
bus_id
,
(
u32
)
dev
->
wakeup
.
sleep_state
);
if
(
!
dev
->
physical_node_count
)
if
(
!
dev
->
physical_node_count
)
{
seq_printf
(
seq
,
"%c%-8s
\n
"
,
dev
->
wakeup
.
flags
.
run_wake
?
'*'
:
' '
,
"disabled"
);
else
{
dev
->
wakeup
.
flags
.
run_wake
?
'*'
:
' '
,
device_may_wakeup
(
&
dev
->
dev
)
?
"enabled"
:
"disabled"
);
}
else
{
struct
device
*
ldev
;
list_for_each_entry
(
entry
,
&
dev
->
physical_node_list
,
node
)
{
...
...
drivers/acpi/scan.c
浏览文件 @
8a78cf70
...
...
@@ -178,6 +178,32 @@ void acpi_bus_hot_remove_device(void *context)
}
EXPORT_SYMBOL
(
acpi_bus_hot_remove_device
);
static
ssize_t
real_power_state_show
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
acpi_device
*
adev
=
to_acpi_device
(
dev
);
int
state
;
int
ret
;
ret
=
acpi_device_get_power
(
adev
,
&
state
);
if
(
ret
)
return
ret
;
return
sprintf
(
buf
,
"%s
\n
"
,
acpi_power_state_string
(
state
));
}
static
DEVICE_ATTR
(
real_power_state
,
0444
,
real_power_state_show
,
NULL
);
static
ssize_t
power_state_show
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
acpi_device
*
adev
=
to_acpi_device
(
dev
);
return
sprintf
(
buf
,
"%s
\n
"
,
acpi_power_state_string
(
adev
->
power
.
state
));
}
static
DEVICE_ATTR
(
power_state
,
0444
,
power_state_show
,
NULL
);
static
ssize_t
acpi_eject_store
(
struct
device
*
d
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
...
...
@@ -369,8 +395,22 @@ static int acpi_device_setup_files(struct acpi_device *dev)
* hot-removal function from userland.
*/
status
=
acpi_get_handle
(
dev
->
handle
,
"_EJ0"
,
&
temp
);
if
(
ACPI_SUCCESS
(
status
))
if
(
ACPI_SUCCESS
(
status
))
{
result
=
device_create_file
(
&
dev
->
dev
,
&
dev_attr_eject
);
if
(
result
)
return
result
;
}
if
(
dev
->
flags
.
power_manageable
)
{
result
=
device_create_file
(
&
dev
->
dev
,
&
dev_attr_power_state
);
if
(
result
)
return
result
;
if
(
dev
->
power
.
flags
.
power_resources
)
result
=
device_create_file
(
&
dev
->
dev
,
&
dev_attr_real_power_state
);
}
end:
return
result
;
}
...
...
@@ -380,6 +420,13 @@ static void acpi_device_remove_files(struct acpi_device *dev)
acpi_status
status
;
acpi_handle
temp
;
if
(
dev
->
flags
.
power_manageable
)
{
device_remove_file
(
&
dev
->
dev
,
&
dev_attr_power_state
);
if
(
dev
->
power
.
flags
.
power_resources
)
device_remove_file
(
&
dev
->
dev
,
&
dev_attr_real_power_state
);
}
/*
* If device has _STR, remove 'description' file
*/
...
...
@@ -464,7 +511,7 @@ int acpi_match_device_ids(struct acpi_device *device,
}
EXPORT_SYMBOL
(
acpi_match_device_ids
);
static
void
acpi_free_ids
(
struct
acpi_device
*
device
)
void
acpi_free_ids
(
struct
acpi_device
*
device
)
{
struct
acpi_hardware_id
*
id
,
*
tmp
;
...
...
@@ -472,6 +519,23 @@ static void acpi_free_ids(struct acpi_device *device)
kfree
(
id
->
id
);
kfree
(
id
);
}
kfree
(
device
->
pnp
.
unique_id
);
}
static
void
acpi_free_power_resources_lists
(
struct
acpi_device
*
device
)
{
int
i
;
if
(
device
->
wakeup
.
flags
.
valid
)
acpi_power_resources_list_free
(
&
device
->
wakeup
.
resources
);
if
(
!
device
->
flags
.
power_manageable
)
return
;
for
(
i
=
ACPI_STATE_D0
;
i
<=
ACPI_STATE_D3_HOT
;
i
++
)
{
struct
acpi_device_power_state
*
ps
=
&
device
->
power
.
states
[
i
];
acpi_power_resources_list_free
(
&
ps
->
resources
);
}
}
static
void
acpi_device_release
(
struct
device
*
dev
)
...
...
@@ -479,7 +543,7 @@ static void acpi_device_release(struct device *dev)
struct
acpi_device
*
acpi_dev
=
to_acpi_device
(
dev
);
acpi_free_ids
(
acpi_dev
);
kfree
(
acpi_dev
->
pnp
.
unique_id
);
acpi_free_power_resources_lists
(
acpi_dev
);
kfree
(
acpi_dev
);
}
...
...
@@ -616,12 +680,25 @@ struct bus_type acpi_bus_type = {
.
uevent
=
acpi_device_uevent
,
};
static
int
acpi_device_register
(
struct
acpi_device
*
device
)
int
acpi_device_add
(
struct
acpi_device
*
device
,
void
(
*
release
)(
struct
device
*
))
{
int
result
;
struct
acpi_device_bus_id
*
acpi_device_bus_id
,
*
new_bus_id
;
int
found
=
0
;
if
(
device
->
handle
)
{
acpi_status
status
;
status
=
acpi_attach_data
(
device
->
handle
,
acpi_bus_data_handler
,
device
);
if
(
ACPI_FAILURE
(
status
))
{
acpi_handle_err
(
device
->
handle
,
"Unable to attach device data
\n
"
);
return
-
ENODEV
;
}
}
/*
* Linkage
* -------
...
...
@@ -632,11 +709,13 @@ static int acpi_device_register(struct acpi_device *device)
INIT_LIST_HEAD
(
&
device
->
wakeup_list
);
INIT_LIST_HEAD
(
&
device
->
physical_node_list
);
mutex_init
(
&
device
->
physical_node_lock
);
INIT_LIST_HEAD
(
&
device
->
power_dependent
);
new_bus_id
=
kzalloc
(
sizeof
(
struct
acpi_device_bus_id
),
GFP_KERNEL
);
if
(
!
new_bus_id
)
{
printk
(
KERN_ERR
PREFIX
"Memory allocation error
\n
"
);
return
-
ENOMEM
;
pr_err
(
PREFIX
"Memory allocation error
\n
"
);
result
=
-
ENOMEM
;
goto
err_detach
;
}
mutex_lock
(
&
acpi_device_lock
);
...
...
@@ -671,11 +750,11 @@ static int acpi_device_register(struct acpi_device *device)
if
(
device
->
parent
)
device
->
dev
.
parent
=
&
device
->
parent
->
dev
;
device
->
dev
.
bus
=
&
acpi_bus_type
;
device
->
dev
.
release
=
&
acpi_device_
release
;
result
=
device_
register
(
&
device
->
dev
);
device
->
dev
.
release
=
release
;
result
=
device_
add
(
&
device
->
dev
);
if
(
result
)
{
dev_err
(
&
device
->
dev
,
"Error registering device
\n
"
);
goto
e
nd
;
goto
e
rr
;
}
result
=
acpi_device_setup_files
(
device
);
...
...
@@ -685,12 +764,16 @@ static int acpi_device_register(struct acpi_device *device)
device
->
removal_type
=
ACPI_BUS_REMOVAL_NORMAL
;
return
0
;
end:
err:
mutex_lock
(
&
acpi_device_lock
);
if
(
device
->
parent
)
list_del
(
&
device
->
node
);
list_del
(
&
device
->
wakeup_list
);
mutex_unlock
(
&
acpi_device_lock
);
err_detach:
acpi_detach_data
(
device
->
handle
,
acpi_bus_data_handler
);
return
result
;
}
...
...
@@ -705,8 +788,18 @@ static void acpi_device_unregister(struct acpi_device *device)
acpi_detach_data
(
device
->
handle
,
acpi_bus_data_handler
);
acpi_power_add_remove_device
(
device
,
false
);
acpi_device_remove_files
(
device
);
device_unregister
(
&
device
->
dev
);
if
(
device
->
remove
)
device
->
remove
(
device
);
device_del
(
&
device
->
dev
);
/*
* Drop the reference counts of all power resources the device depends
* on and turn off the ones that have no more references.
*/
acpi_power_transition
(
device
,
ACPI_STATE_D3_COLD
);
put_device
(
&
device
->
dev
);
}
/* --------------------------------------------------------------------------
...
...
@@ -849,52 +942,43 @@ void acpi_bus_data_handler(acpi_handle handle, void *context)
return
;
}
static
int
acpi_bus_get_perf_flags
(
struct
acpi_device
*
device
)
{
device
->
performance
.
state
=
ACPI_STATE_UNKNOWN
;
return
0
;
}
static
acpi_status
acpi_bus_extract_wakeup_device_power_package
(
acpi_handle
handle
,
struct
acpi_device_wakeup
*
wakeup
)
static
int
acpi_bus_extract_wakeup_device_power_package
(
acpi_handle
handle
,
struct
acpi_device_wakeup
*
wakeup
)
{
struct
acpi_buffer
buffer
=
{
ACPI_ALLOCATE_BUFFER
,
NULL
};
union
acpi_object
*
package
=
NULL
;
union
acpi_object
*
element
=
NULL
;
acpi_status
status
;
int
i
=
0
;
int
err
=
-
ENODATA
;
if
(
!
wakeup
)
return
AE_BAD_PARAMETER
;
return
-
EINVAL
;
INIT_LIST_HEAD
(
&
wakeup
->
resources
);
/* _PRW */
status
=
acpi_evaluate_object
(
handle
,
"_PRW"
,
NULL
,
&
buffer
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_EXCEPTION
((
AE_INFO
,
status
,
"Evaluating _PRW"
));
return
status
;
return
err
;
}
package
=
(
union
acpi_object
*
)
buffer
.
pointer
;
if
(
!
package
||
(
package
->
package
.
count
<
2
))
{
status
=
AE_BAD_DATA
;
if
(
!
package
||
package
->
package
.
count
<
2
)
goto
out
;
}
element
=
&
(
package
->
package
.
elements
[
0
]);
if
(
!
element
)
{
status
=
AE_BAD_DATA
;
if
(
!
element
)
goto
out
;
}
if
(
element
->
type
==
ACPI_TYPE_PACKAGE
)
{
if
((
element
->
package
.
count
<
2
)
||
(
element
->
package
.
elements
[
0
].
type
!=
ACPI_TYPE_LOCAL_REFERENCE
)
||
(
element
->
package
.
elements
[
1
].
type
!=
ACPI_TYPE_INTEGER
))
{
status
=
AE_BAD_DATA
;
||
(
element
->
package
.
elements
[
1
].
type
!=
ACPI_TYPE_INTEGER
))
goto
out
;
}
wakeup
->
gpe_device
=
element
->
package
.
elements
[
0
].
reference
.
handle
;
wakeup
->
gpe_number
=
...
...
@@ -903,38 +987,35 @@ acpi_bus_extract_wakeup_device_power_package(acpi_handle handle,
wakeup
->
gpe_device
=
NULL
;
wakeup
->
gpe_number
=
element
->
integer
.
value
;
}
else
{
status
=
AE_BAD_DATA
;
goto
out
;
}
element
=
&
(
package
->
package
.
elements
[
1
]);
if
(
element
->
type
!=
ACPI_TYPE_INTEGER
)
{
status
=
AE_BAD_DATA
;
if
(
element
->
type
!=
ACPI_TYPE_INTEGER
)
goto
out
;
}
wakeup
->
sleep_state
=
element
->
integer
.
value
;
if
((
package
->
package
.
count
-
2
)
>
ACPI_MAX_HANDLES
)
{
status
=
AE_NO_MEMORY
;
err
=
acpi_extract_power_resources
(
package
,
2
,
&
wakeup
->
resources
);
if
(
err
)
goto
out
;
}
wakeup
->
resources
.
count
=
package
->
package
.
count
-
2
;
for
(
i
=
0
;
i
<
wakeup
->
resources
.
count
;
i
++
)
{
element
=
&
(
package
->
package
.
elements
[
i
+
2
]);
if
(
element
->
type
!=
ACPI_TYPE_LOCAL_REFERENCE
)
{
status
=
AE_BAD_DATA
;
goto
out
;
}
wakeup
->
resources
.
handles
[
i
]
=
element
->
reference
.
handle
;
}
if
(
!
list_empty
(
&
wakeup
->
resources
))
{
int
sleep_state
;
sleep_state
=
acpi_power_min_system_level
(
&
wakeup
->
resources
);
if
(
sleep_state
<
wakeup
->
sleep_state
)
{
acpi_handle_warn
(
handle
,
"Overriding _PRW sleep state "
"(S%d) by S%d from power resources
\n
"
,
(
int
)
wakeup
->
sleep_state
,
sleep_state
);
wakeup
->
sleep_state
=
sleep_state
;
}
}
acpi_setup_gpe_for_wake
(
handle
,
wakeup
->
gpe_device
,
wakeup
->
gpe_number
);
out:
kfree
(
buffer
.
pointer
);
return
status
;
return
err
;
}
static
void
acpi_bus_set_run_wake_flags
(
struct
acpi_device
*
device
)
...
...
@@ -974,17 +1055,17 @@ static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
{
acpi_handle
temp
;
acpi_status
status
=
0
;
int
psw_erro
r
;
int
er
r
;
/* Presence of _PRW indicates wake capable */
status
=
acpi_get_handle
(
device
->
handle
,
"_PRW"
,
&
temp
);
if
(
ACPI_FAILURE
(
status
))
return
;
status
=
acpi_bus_extract_wakeup_device_power_package
(
device
->
handle
,
&
device
->
wakeup
);
if
(
ACPI_FAILURE
(
status
)
)
{
ACPI_EXCEPTION
((
AE_INFO
,
status
,
"Extracting _PRW package"
)
);
err
=
acpi_bus_extract_wakeup_device_power_package
(
device
->
handle
,
&
device
->
wakeup
);
if
(
err
)
{
dev_err
(
&
device
->
dev
,
"_PRW evaluation error: %d
\n
"
,
err
);
return
;
}
...
...
@@ -997,20 +1078,73 @@ static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
* So it is necessary to call _DSW object first. Only when it is not
* present will the _PSW object used.
*/
psw_erro
r
=
acpi_device_sleep_wake
(
device
,
0
,
0
,
0
);
if
(
psw_erro
r
)
er
r
=
acpi_device_sleep_wake
(
device
,
0
,
0
,
0
);
if
(
er
r
)
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"error in _DSW or _PSW evaluation
\n
"
));
}
static
void
acpi_bus_add_power_resource
(
acpi_handle
handle
);
static
void
acpi_bus_init_power_state
(
struct
acpi_device
*
device
,
int
state
)
{
struct
acpi_device_power_state
*
ps
=
&
device
->
power
.
states
[
state
];
char
pathname
[
5
]
=
{
'_'
,
'P'
,
'R'
,
'0'
+
state
,
'\0'
};
struct
acpi_buffer
buffer
=
{
ACPI_ALLOCATE_BUFFER
,
NULL
};
acpi_handle
handle
;
acpi_status
status
;
static
int
acpi_bus_get_power_flags
(
struct
acpi_device
*
device
)
INIT_LIST_HEAD
(
&
ps
->
resources
);
/* Evaluate "_PRx" to get referenced power resources */
status
=
acpi_evaluate_object
(
device
->
handle
,
pathname
,
NULL
,
&
buffer
);
if
(
ACPI_SUCCESS
(
status
))
{
union
acpi_object
*
package
=
buffer
.
pointer
;
if
(
buffer
.
length
&&
package
&&
package
->
type
==
ACPI_TYPE_PACKAGE
&&
package
->
package
.
count
)
{
int
err
=
acpi_extract_power_resources
(
package
,
0
,
&
ps
->
resources
);
if
(
!
err
)
device
->
power
.
flags
.
power_resources
=
1
;
}
ACPI_FREE
(
buffer
.
pointer
);
}
/* Evaluate "_PSx" to see if we can do explicit sets */
pathname
[
2
]
=
'S'
;
status
=
acpi_get_handle
(
device
->
handle
,
pathname
,
&
handle
);
if
(
ACPI_SUCCESS
(
status
))
ps
->
flags
.
explicit_set
=
1
;
/*
* State is valid if there are means to put the device into it.
* D3hot is only valid if _PR3 present.
*/
if
(
!
list_empty
(
&
ps
->
resources
)
||
(
ps
->
flags
.
explicit_set
&&
state
<
ACPI_STATE_D3_HOT
))
{
ps
->
flags
.
valid
=
1
;
ps
->
flags
.
os_accessible
=
1
;
}
ps
->
power
=
-
1
;
/* Unknown - driver assigned */
ps
->
latency
=
-
1
;
/* Unknown - driver assigned */
}
static
void
acpi_bus_get_power_flags
(
struct
acpi_device
*
device
)
{
acpi_status
status
=
0
;
acpi_handle
handle
=
NULL
;
u32
i
=
0
;
acpi_status
status
;
acpi_handle
handle
;
u32
i
;
/* Presence of _PS0|_PR0 indicates 'power manageable' */
status
=
acpi_get_handle
(
device
->
handle
,
"_PS0"
,
&
handle
);
if
(
ACPI_FAILURE
(
status
))
{
status
=
acpi_get_handle
(
device
->
handle
,
"_PR0"
,
&
handle
);
if
(
ACPI_FAILURE
(
status
))
return
;
}
device
->
flags
.
power_manageable
=
1
;
/*
* Power Management Flags
...
...
@@ -1025,40 +1159,10 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
/*
* Enumerate supported power management states
*/
for
(
i
=
ACPI_STATE_D0
;
i
<=
ACPI_STATE_D3_HOT
;
i
++
)
{
struct
acpi_device_power_state
*
ps
=
&
device
->
power
.
states
[
i
];
char
object_name
[
5
]
=
{
'_'
,
'P'
,
'R'
,
'0'
+
i
,
'\0'
};
/* Evaluate "_PRx" to se if power resources are referenced */
acpi_evaluate_reference
(
device
->
handle
,
object_name
,
NULL
,
&
ps
->
resources
);
if
(
ps
->
resources
.
count
)
{
int
j
;
for
(
i
=
ACPI_STATE_D0
;
i
<=
ACPI_STATE_D3_HOT
;
i
++
)
acpi_bus_init_power_state
(
device
,
i
);
device
->
power
.
flags
.
power_resources
=
1
;
for
(
j
=
0
;
j
<
ps
->
resources
.
count
;
j
++
)
acpi_bus_add_power_resource
(
ps
->
resources
.
handles
[
j
]);
}
/* Evaluate "_PSx" to see if we can do explicit sets */
object_name
[
2
]
=
'S'
;
status
=
acpi_get_handle
(
device
->
handle
,
object_name
,
&
handle
);
if
(
ACPI_SUCCESS
(
status
))
ps
->
flags
.
explicit_set
=
1
;
/*
* State is valid if there are means to put the device into it.
* D3hot is only valid if _PR3 present.
*/
if
(
ps
->
resources
.
count
||
(
ps
->
flags
.
explicit_set
&&
i
<
ACPI_STATE_D3_HOT
))
{
ps
->
flags
.
valid
=
1
;
ps
->
flags
.
os_accessible
=
1
;
}
ps
->
power
=
-
1
;
/* Unknown - driver assigned */
ps
->
latency
=
-
1
;
/* Unknown - driver assigned */
}
INIT_LIST_HEAD
(
&
device
->
power
.
states
[
ACPI_STATE_D3_COLD
].
resources
);
/* Set defaults for D0 and D3 states (always valid) */
device
->
power
.
states
[
ACPI_STATE_D0
].
flags
.
valid
=
1
;
...
...
@@ -1076,16 +1180,13 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
device
->
power
.
states
[
ACPI_STATE_D3_COLD
].
flags
.
os_accessible
=
1
;
acpi_bus_init_power
(
device
);
return
0
;
}
static
int
acpi_bus_get_flags
(
struct
acpi_device
*
device
)
static
void
acpi_bus_get_flags
(
struct
acpi_device
*
device
)
{
acpi_status
status
=
AE_OK
;
acpi_handle
temp
=
NULL
;
/* Presence of _STA indicates 'dynamic_status' */
status
=
acpi_get_handle
(
device
->
handle
,
"_STA"
,
&
temp
);
if
(
ACPI_SUCCESS
(
status
))
...
...
@@ -1105,21 +1206,6 @@ static int acpi_bus_get_flags(struct acpi_device *device)
if
(
ACPI_SUCCESS
(
status
))
device
->
flags
.
ejectable
=
1
;
}
/* Power resources cannot be power manageable. */
if
(
device
->
device_type
==
ACPI_BUS_TYPE_POWER
)
return
0
;
/* Presence of _PS0|_PR0 indicates 'power manageable' */
status
=
acpi_get_handle
(
device
->
handle
,
"_PS0"
,
&
temp
);
if
(
ACPI_FAILURE
(
status
))
status
=
acpi_get_handle
(
device
->
handle
,
"_PR0"
,
&
temp
);
if
(
ACPI_SUCCESS
(
status
))
device
->
flags
.
power_manageable
=
1
;
/* TBD: Performance management */
return
0
;
}
static
void
acpi_device_get_busid
(
struct
acpi_device
*
device
)
...
...
@@ -1344,27 +1430,25 @@ static void acpi_device_set_id(struct acpi_device *device)
}
}
static
int
acpi_device_set_context
(
struct
acpi_device
*
device
)
void
acpi_init_device_object
(
struct
acpi_device
*
device
,
acpi_handle
handle
,
int
type
,
unsigned
long
long
sta
)
{
acpi_status
status
;
/*
* Context
* -------
* Attach this 'struct acpi_device' to the ACPI object. This makes
* resolutions from handle->device very efficient. Fixed hardware
* devices have no handles, so we skip them.
*/
if
(
!
device
->
handle
)
return
0
;
status
=
acpi_attach_data
(
device
->
handle
,
acpi_bus_data_handler
,
device
);
if
(
ACPI_SUCCESS
(
status
))
return
0
;
INIT_LIST_HEAD
(
&
device
->
pnp
.
ids
);
device
->
device_type
=
type
;
device
->
handle
=
handle
;
device
->
parent
=
acpi_bus_get_parent
(
handle
);
STRUCT_TO_INT
(
device
->
status
)
=
sta
;
acpi_device_get_busid
(
device
);
acpi_device_set_id
(
device
);
acpi_bus_get_flags
(
device
);
device_initialize
(
&
device
->
dev
);
dev_set_uevent_suppress
(
&
device
->
dev
,
true
);
}
printk
(
KERN_ERR
PREFIX
"Error attaching device data
\n
"
);
return
-
ENODEV
;
void
acpi_device_add_finalize
(
struct
acpi_device
*
device
)
{
dev_set_uevent_suppress
(
&
device
->
dev
,
false
);
kobject_uevent
(
&
device
->
dev
.
kobj
,
KOBJ_ADD
);
}
static
int
acpi_add_single_object
(
struct
acpi_device
**
child
,
...
...
@@ -1381,90 +1465,26 @@ static int acpi_add_single_object(struct acpi_device **child,
return
-
ENOMEM
;
}
INIT_LIST_HEAD
(
&
device
->
pnp
.
ids
);
device
->
device_type
=
type
;
device
->
handle
=
handle
;
device
->
parent
=
acpi_bus_get_parent
(
handle
);
STRUCT_TO_INT
(
device
->
status
)
=
sta
;
acpi_device_get_busid
(
device
);
/*
* Flags
* -----
* Note that we only look for object handles -- cannot evaluate objects
* until we know the device is present and properly initialized.
*/
result
=
acpi_bus_get_flags
(
device
);
if
(
result
)
goto
end
;
/*
* Initialize Device
* -----------------
* TBD: Synch with Core's enumeration/initialization process.
*/
acpi_device_set_id
(
device
);
/*
* Power Management
* ----------------
*/
if
(
device
->
flags
.
power_manageable
)
{
result
=
acpi_bus_get_power_flags
(
device
);
if
(
result
)
goto
end
;
}
/*
* Wakeup device management
*-----------------------
*/
acpi_init_device_object
(
device
,
handle
,
type
,
sta
);
acpi_bus_get_power_flags
(
device
);
acpi_bus_get_wakeup_device_flags
(
device
);
/*
* Performance Management
* ----------------------
*/
if
(
device
->
flags
.
performance_manageable
)
{
result
=
acpi_bus_get_perf_flags
(
device
);
if
(
result
)
goto
end
;
}
if
((
result
=
acpi_device_set_context
(
device
)))
goto
end
;
device
->
flags
.
match_driver
=
match_driver
;
result
=
acpi_device_register
(
device
);
end:
if
(
!
result
)
{
acpi_get_name
(
handle
,
ACPI_FULL_PATHNAME
,
&
buffer
);
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Adding %s [%s] parent %s
\n
"
,
dev_name
(
&
device
->
dev
),
(
char
*
)
buffer
.
pointer
,
device
->
parent
?
dev_name
(
&
device
->
parent
->
dev
)
:
"(null)"
));
kfree
(
buffer
.
pointer
);
*
child
=
device
;
}
else
result
=
acpi_device_add
(
device
,
acpi_device_release
);
if
(
result
)
{
acpi_device_release
(
&
device
->
dev
);
return
result
;
}
return
result
;
}
#define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \
ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING)
static
void
acpi_bus_add_power_resource
(
acpi_handle
handle
)
{
struct
acpi_device
*
device
=
NULL
;
acpi_bus_get_device
(
handle
,
&
device
);
if
(
!
device
)
acpi_add_single_object
(
&
device
,
handle
,
ACPI_BUS_TYPE_POWER
,
ACPI_STA_DEFAULT
,
true
);
acpi_power_add_remove_device
(
device
,
true
);
acpi_device_add_finalize
(
device
);
acpi_get_name
(
handle
,
ACPI_FULL_PATHNAME
,
&
buffer
);
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Added %s [%s] parent %s
\n
"
,
dev_name
(
&
device
->
dev
),
(
char
*
)
buffer
.
pointer
,
device
->
parent
?
dev_name
(
&
device
->
parent
->
dev
)
:
"(null)"
));
kfree
(
buffer
.
pointer
);
*
child
=
device
;
return
0
;
}
static
int
acpi_bus_type_and_status
(
acpi_handle
handle
,
int
*
type
,
...
...
@@ -1523,20 +1543,26 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used,
if
(
result
)
return
AE_OK
;
if
(
type
==
ACPI_BUS_TYPE_POWER
)
{
acpi_add_power_resource
(
handle
);
return
AE_OK
;
}
if
(
!
(
sta
&
ACPI_STA_DEVICE_PRESENT
)
&&
!
(
sta
&
ACPI_STA_DEVICE_FUNCTIONING
))
{
struct
acpi_device_wakeup
wakeup
;
acpi_handle
temp
;
status
=
acpi_get_handle
(
handle
,
"_PRW"
,
&
temp
);
if
(
ACPI_SUCCESS
(
status
))
if
(
ACPI_SUCCESS
(
status
))
{
acpi_bus_extract_wakeup_device_power_package
(
handle
,
&
wakeup
);
acpi_power_resources_list_free
(
&
wakeup
.
resources
);
}
return
AE_CTRL_DEPTH
;
}
acpi_add_single_object
(
&
device
,
handle
,
type
,
sta
,
type
==
ACPI_BUS_TYPE_POWER
);
acpi_add_single_object
(
&
device
,
handle
,
type
,
sta
,
false
);
if
(
!
device
)
return
AE_CTRL_DEPTH
;
...
...
@@ -1684,7 +1710,6 @@ int __init acpi_scan_init(void)
printk
(
KERN_ERR
PREFIX
"Could not register bus type
\n
"
);
}
acpi_power_init
();
acpi_pci_root_init
();
/*
...
...
drivers/acpi/sleep.c
浏览文件 @
8a78cf70
...
...
@@ -386,6 +386,8 @@ static void acpi_pm_finish(void)
acpi_target_sleep_state
=
ACPI_STATE_S0
;
acpi_resume_power_resources
();
/* If we were woken with the fixed power button, provide a small
* hint to userspace in the form of a wakeup event on the fixed power
* button device (if it can be found).
...
...
@@ -577,7 +579,28 @@ static const struct platform_suspend_ops acpi_suspend_ops_old = {
.
end
=
acpi_pm_end
,
.
recover
=
acpi_pm_finish
,
};
#endif
/* CONFIG_SUSPEND */
static
void
acpi_sleep_suspend_setup
(
void
)
{
int
i
;
for
(
i
=
ACPI_STATE_S1
;
i
<
ACPI_STATE_S4
;
i
++
)
{
acpi_status
status
;
u8
type_a
,
type_b
;
status
=
acpi_get_sleep_type_data
(
i
,
&
type_a
,
&
type_b
);
if
(
ACPI_SUCCESS
(
status
))
{
sleep_states
[
i
]
=
1
;
pr_cont
(
" S%d"
,
i
);
}
}
suspend_set_ops
(
old_suspend_ordering
?
&
acpi_suspend_ops_old
:
&
acpi_suspend_ops
);
}
#else
/* !CONFIG_SUSPEND */
static
inline
void
acpi_sleep_suspend_setup
(
void
)
{}
#endif
/* !CONFIG_SUSPEND */
#ifdef CONFIG_HIBERNATION
static
unsigned
long
s4_hardware_signature
;
...
...
@@ -698,7 +721,30 @@ static const struct platform_hibernation_ops acpi_hibernation_ops_old = {
.
restore_cleanup
=
acpi_pm_thaw
,
.
recover
=
acpi_pm_finish
,
};
#endif
/* CONFIG_HIBERNATION */
static
void
acpi_sleep_hibernate_setup
(
void
)
{
acpi_status
status
;
u8
type_a
,
type_b
;
status
=
acpi_get_sleep_type_data
(
ACPI_STATE_S4
,
&
type_a
,
&
type_b
);
if
(
ACPI_FAILURE
(
status
))
return
;
hibernation_set_ops
(
old_suspend_ordering
?
&
acpi_hibernation_ops_old
:
&
acpi_hibernation_ops
);
sleep_states
[
ACPI_STATE_S4
]
=
1
;
pr_cont
(
KERN_CONT
" S4"
);
if
(
nosigcheck
)
return
;
acpi_get_table
(
ACPI_SIG_FACS
,
1
,
(
struct
acpi_table_header
**
)
&
facs
);
if
(
facs
)
s4_hardware_signature
=
facs
->
hardware_signature
;
}
#else
/* !CONFIG_HIBERNATION */
static
inline
void
acpi_sleep_hibernate_setup
(
void
)
{}
#endif
/* !CONFIG_HIBERNATION */
int
acpi_suspend
(
u32
acpi_state
)
{
...
...
@@ -734,9 +780,6 @@ int __init acpi_sleep_init(void)
{
acpi_status
status
;
u8
type_a
,
type_b
;
#ifdef CONFIG_SUSPEND
int
i
=
0
;
#endif
if
(
acpi_disabled
)
return
0
;
...
...
@@ -744,45 +787,19 @@ int __init acpi_sleep_init(void)
acpi_sleep_dmi_check
();
sleep_states
[
ACPI_STATE_S0
]
=
1
;
pr
intk
(
KERN_INFO
PREFIX
"(supports S0"
);
pr
_info
(
PREFIX
"(supports S0"
);
#ifdef CONFIG_SUSPEND
for
(
i
=
ACPI_STATE_S1
;
i
<
ACPI_STATE_S4
;
i
++
)
{
status
=
acpi_get_sleep_type_data
(
i
,
&
type_a
,
&
type_b
);
if
(
ACPI_SUCCESS
(
status
))
{
sleep_states
[
i
]
=
1
;
printk
(
KERN_CONT
" S%d"
,
i
);
}
}
acpi_sleep_suspend_setup
();
acpi_sleep_hibernate_setup
();
suspend_set_ops
(
old_suspend_ordering
?
&
acpi_suspend_ops_old
:
&
acpi_suspend_ops
);
#endif
#ifdef CONFIG_HIBERNATION
status
=
acpi_get_sleep_type_data
(
ACPI_STATE_S4
,
&
type_a
,
&
type_b
);
if
(
ACPI_SUCCESS
(
status
))
{
hibernation_set_ops
(
old_suspend_ordering
?
&
acpi_hibernation_ops_old
:
&
acpi_hibernation_ops
);
sleep_states
[
ACPI_STATE_S4
]
=
1
;
printk
(
KERN_CONT
" S4"
);
if
(
!
nosigcheck
)
{
acpi_get_table
(
ACPI_SIG_FACS
,
1
,
(
struct
acpi_table_header
**
)
&
facs
);
if
(
facs
)
s4_hardware_signature
=
facs
->
hardware_signature
;
}
}
#endif
status
=
acpi_get_sleep_type_data
(
ACPI_STATE_S5
,
&
type_a
,
&
type_b
);
if
(
ACPI_SUCCESS
(
status
))
{
sleep_states
[
ACPI_STATE_S5
]
=
1
;
pr
intk
(
KERN_CONT
" S5"
);
pr
_cont
(
" S5"
);
pm_power_off_prepare
=
acpi_power_off_prepare
;
pm_power_off
=
acpi_power_off
;
}
pr
intk
(
KERN_CONT
")
\n
"
);
pr
_cont
(
")
\n
"
);
/*
* Register the tts_notifier to reboot notifier list so that the _TTS
* object can also be evaluated when the system enters S5.
...
...
drivers/acpi/sleep.h
浏览文件 @
8a78cf70
...
...
@@ -6,3 +6,5 @@ extern void acpi_disable_wakeup_devices(u8 sleep_state);
extern
struct
list_head
acpi_wakeup_device_list
;
extern
struct
mutex
acpi_device_lock
;
extern
void
acpi_resume_power_resources
(
void
);
drivers/ata/libata-acpi.c
浏览文件 @
8a78cf70
...
...
@@ -1029,30 +1029,20 @@ static void ata_acpi_register_power_resource(struct ata_device *dev)
{
struct
scsi_device
*
sdev
=
dev
->
sdev
;
acpi_handle
handle
;
struct
device
*
device
;
handle
=
ata_dev_acpi_handle
(
dev
);
if
(
!
handle
)
return
;
device
=
&
sdev
->
sdev_gendev
;
acpi_power_resource_register_device
(
device
,
handle
);
if
(
handle
)
acpi_dev_pm_remove_dependent
(
handle
,
&
sdev
->
sdev_gendev
);
}
static
void
ata_acpi_unregister_power_resource
(
struct
ata_device
*
dev
)
{
struct
scsi_device
*
sdev
=
dev
->
sdev
;
acpi_handle
handle
;
struct
device
*
device
;
handle
=
ata_dev_acpi_handle
(
dev
);
if
(
!
handle
)
return
;
device
=
&
sdev
->
sdev_gendev
;
acpi_power_resource_unregister_device
(
device
,
handle
);
if
(
handle
)
acpi_dev_pm_remove_dependent
(
handle
,
&
sdev
->
sdev_gendev
);
}
void
ata_acpi_bind
(
struct
ata_device
*
dev
)
...
...
drivers/pci/pci-acpi.c
浏览文件 @
8a78cf70
...
...
@@ -345,7 +345,6 @@ static void pci_acpi_setup(struct device *dev)
acpi_pci_irq_add_prt
(
handle
,
pci_domain_nr
(
pci_dev
->
bus
),
bus
);
}
acpi_power_resource_register_device
(
dev
,
handle
);
if
(
acpi_bus_get_device
(
handle
,
&
adev
)
||
!
adev
->
wakeup
.
flags
.
valid
)
return
;
...
...
@@ -368,7 +367,6 @@ static void pci_acpi_cleanup(struct device *dev)
device_set_run_wake
(
dev
,
false
);
pci_acpi_remove_pm_notifier
(
adev
);
}
acpi_power_resource_unregister_device
(
dev
,
handle
);
if
(
pci_dev
->
subordinate
)
acpi_pci_irq_del_prt
(
pci_domain_nr
(
pci_dev
->
bus
),
...
...
fs/sysfs/group.c
浏览文件 @
8a78cf70
...
...
@@ -205,6 +205,48 @@ void sysfs_unmerge_group(struct kobject *kobj,
}
EXPORT_SYMBOL_GPL
(
sysfs_unmerge_group
);
/**
* sysfs_add_link_to_group - add a symlink to an attribute group.
* @kobj: The kobject containing the group.
* @group_name: The name of the group.
* @target: The target kobject of the symlink to create.
* @link_name: The name of the symlink to create.
*/
int
sysfs_add_link_to_group
(
struct
kobject
*
kobj
,
const
char
*
group_name
,
struct
kobject
*
target
,
const
char
*
link_name
)
{
struct
sysfs_dirent
*
dir_sd
;
int
error
=
0
;
dir_sd
=
sysfs_get_dirent
(
kobj
->
sd
,
NULL
,
group_name
);
if
(
!
dir_sd
)
return
-
ENOENT
;
error
=
sysfs_create_link_sd
(
dir_sd
,
target
,
link_name
);
sysfs_put
(
dir_sd
);
return
error
;
}
EXPORT_SYMBOL_GPL
(
sysfs_add_link_to_group
);
/**
* sysfs_remove_link_from_group - remove a symlink from an attribute group.
* @kobj: The kobject containing the group.
* @group_name: The name of the group.
* @link_name: The name of the symlink to remove.
*/
void
sysfs_remove_link_from_group
(
struct
kobject
*
kobj
,
const
char
*
group_name
,
const
char
*
link_name
)
{
struct
sysfs_dirent
*
dir_sd
;
dir_sd
=
sysfs_get_dirent
(
kobj
->
sd
,
NULL
,
group_name
);
if
(
dir_sd
)
{
sysfs_hash_and_remove
(
dir_sd
,
NULL
,
link_name
);
sysfs_put
(
dir_sd
);
}
}
EXPORT_SYMBOL_GPL
(
sysfs_remove_link_from_group
);
EXPORT_SYMBOL_GPL
(
sysfs_create_group
);
EXPORT_SYMBOL_GPL
(
sysfs_update_group
);
...
...
fs/sysfs/symlink.c
浏览文件 @
8a78cf70
...
...
@@ -21,26 +21,17 @@
#include "sysfs.h"
static
int
sysfs_do_create_link
(
struct
kobject
*
kobj
,
struct
kobject
*
target
,
const
char
*
name
,
int
warn
)
static
int
sysfs_do_create_link_sd
(
struct
sysfs_dirent
*
parent_sd
,
struct
kobject
*
target
,
const
char
*
name
,
int
warn
)
{
struct
sysfs_dirent
*
parent_sd
=
NULL
;
struct
sysfs_dirent
*
target_sd
=
NULL
;
struct
sysfs_dirent
*
sd
=
NULL
;
struct
sysfs_addrm_cxt
acxt
;
enum
kobj_ns_type
ns_type
;
int
error
;
BUG_ON
(
!
name
);
if
(
!
kobj
)
parent_sd
=
&
sysfs_root
;
else
parent_sd
=
kobj
->
sd
;
error
=
-
EFAULT
;
if
(
!
parent_sd
)
goto
out_put
;
BUG_ON
(
!
name
||
!
parent_sd
);
/* target->sd can go away beneath us but is protected with
* sysfs_assoc_lock. Fetch target_sd from it.
...
...
@@ -95,6 +86,34 @@ static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target,
return
error
;
}
/**
* sysfs_create_link_sd - create symlink to a given object.
* @sd: directory we're creating the link in.
* @target: object we're pointing to.
* @name: name of the symlink.
*/
int
sysfs_create_link_sd
(
struct
sysfs_dirent
*
sd
,
struct
kobject
*
target
,
const
char
*
name
)
{
return
sysfs_do_create_link_sd
(
sd
,
target
,
name
,
1
);
}
static
int
sysfs_do_create_link
(
struct
kobject
*
kobj
,
struct
kobject
*
target
,
const
char
*
name
,
int
warn
)
{
struct
sysfs_dirent
*
parent_sd
=
NULL
;
if
(
!
kobj
)
parent_sd
=
&
sysfs_root
;
else
parent_sd
=
kobj
->
sd
;
if
(
!
parent_sd
)
return
-
EFAULT
;
return
sysfs_do_create_link_sd
(
parent_sd
,
target
,
name
,
warn
);
}
/**
* sysfs_create_link - create symlink between two objects.
* @kobj: object whose directory we're creating the link in.
...
...
fs/sysfs/sysfs.h
浏览文件 @
8a78cf70
...
...
@@ -240,3 +240,5 @@ void unmap_bin_file(struct sysfs_dirent *attr_sd);
* symlink.c
*/
extern
const
struct
inode_operations
sysfs_symlink_inode_operations
;
int
sysfs_create_link_sd
(
struct
sysfs_dirent
*
sd
,
struct
kobject
*
target
,
const
char
*
name
);
include/acpi/acpi_bus.h
浏览文件 @
8a78cf70
...
...
@@ -197,7 +197,7 @@ struct acpi_device_power_state {
}
flags
;
int
power
;
/* % Power (compared to D0) */
int
latency
;
/* Dx->D0 time (microseconds) */
struct
acpi_handle_list
resources
;
/* Power resources referenced */
struct
list_head
resources
;
/* Power resources referenced */
};
struct
acpi_device_power
{
...
...
@@ -240,7 +240,7 @@ struct acpi_device_wakeup {
acpi_handle
gpe_device
;
u64
gpe_number
;
u64
sleep_state
;
struct
acpi_handle_list
resources
;
struct
list_head
resources
;
struct
acpi_device_wakeup_flags
flags
;
int
prepare_count
;
};
...
...
@@ -277,6 +277,8 @@ struct acpi_device {
struct
list_head
physical_node_list
;
struct
mutex
physical_node_lock
;
DECLARE_BITMAP
(
physical_node_id_bitmap
,
ACPI_MAX_PHYSICAL_NODE
);
struct
list_head
power_dependent
;
void
(
*
remove
)(
struct
acpi_device
*
);
};
static
inline
void
*
acpi_driver_data
(
struct
acpi_device
*
d
)
...
...
@@ -327,13 +329,51 @@ void acpi_bus_data_handler(acpi_handle handle, void *context);
acpi_status
acpi_bus_get_status_handle
(
acpi_handle
handle
,
unsigned
long
long
*
sta
);
int
acpi_bus_get_status
(
struct
acpi_device
*
device
);
#ifdef CONFIG_PM
int
acpi_bus_set_power
(
acpi_handle
handle
,
int
state
);
const
char
*
acpi_power_state_string
(
int
state
);
int
acpi_device_get_power
(
struct
acpi_device
*
device
,
int
*
state
);
int
acpi_device_set_power
(
struct
acpi_device
*
device
,
int
state
);
int
acpi_bus_init_power
(
struct
acpi_device
*
device
);
int
acpi_bus_update_power
(
acpi_handle
handle
,
int
*
state_p
);
bool
acpi_bus_power_manageable
(
acpi_handle
handle
);
bool
acpi_bus_can_wakeup
(
acpi_handle
handle
);
int
acpi_power_resource_register_device
(
struct
device
*
dev
,
acpi_handle
handle
);
void
acpi_power_resource_unregister_device
(
struct
device
*
dev
,
acpi_handle
handle
);
#else
/* !CONFIG_PM */
static
inline
int
acpi_bus_set_power
(
acpi_handle
handle
,
int
state
)
{
return
0
;
}
static
inline
const
char
*
acpi_power_state_string
(
int
state
)
{
return
"D0"
;
}
static
inline
int
acpi_device_get_power
(
struct
acpi_device
*
device
,
int
*
state
)
{
return
0
;
}
static
inline
int
acpi_device_set_power
(
struct
acpi_device
*
device
,
int
state
)
{
return
0
;
}
static
inline
int
acpi_bus_init_power
(
struct
acpi_device
*
device
)
{
return
0
;
}
static
inline
int
acpi_bus_update_power
(
acpi_handle
handle
,
int
*
state_p
)
{
return
0
;
}
static
inline
bool
acpi_bus_power_manageable
(
acpi_handle
handle
)
{
return
false
;
}
static
inline
bool
acpi_bus_can_wakeup
(
acpi_handle
handle
)
{
return
false
;
}
#endif
/* !CONFIG_PM */
#ifdef CONFIG_ACPI_PROC_EVENT
int
acpi_bus_generate_proc_event
(
struct
acpi_device
*
device
,
u8
type
,
int
data
);
int
acpi_bus_generate_proc_event4
(
const
char
*
class
,
const
char
*
bid
,
u8
type
,
int
data
);
...
...
@@ -412,6 +452,8 @@ acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
int
acpi_device_power_state
(
struct
device
*
dev
,
struct
acpi_device
*
adev
,
u32
target_state
,
int
d_max_in
,
int
*
d_min_p
);
int
acpi_pm_device_sleep_state
(
struct
device
*
,
int
*
,
int
);
void
acpi_dev_pm_add_dependent
(
acpi_handle
handle
,
struct
device
*
depdev
);
void
acpi_dev_pm_remove_dependent
(
acpi_handle
handle
,
struct
device
*
depdev
);
#else
static
inline
acpi_status
acpi_add_pm_notifier
(
struct
acpi_device
*
adev
,
acpi_notify_handler
handler
,
...
...
@@ -441,6 +483,10 @@ static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m)
{
return
__acpi_device_power_state
(
m
,
p
);
}
static
inline
void
acpi_dev_pm_add_dependent
(
acpi_handle
handle
,
struct
device
*
depdev
)
{}
static
inline
void
acpi_dev_pm_remove_dependent
(
acpi_handle
handle
,
struct
device
*
depdev
)
{}
#endif
#ifdef CONFIG_PM_RUNTIME
...
...
include/linux/acpi.h
浏览文件 @
8a78cf70
...
...
@@ -511,7 +511,7 @@ static inline int acpi_subsys_runtime_suspend(struct device *dev) { return 0; }
static
inline
int
acpi_subsys_runtime_resume
(
struct
device
*
dev
)
{
return
0
;
}
#endif
#if
def CONFIG_ACPI_SLEEP
#if
defined(CONFIG_ACPI) && defined(CONFIG_PM_SLEEP)
int
acpi_dev_suspend_late
(
struct
device
*
dev
);
int
acpi_dev_resume_early
(
struct
device
*
dev
);
int
acpi_subsys_prepare
(
struct
device
*
dev
);
...
...
include/linux/sysfs.h
浏览文件 @
8a78cf70
...
...
@@ -181,6 +181,10 @@ int sysfs_merge_group(struct kobject *kobj,
const
struct
attribute_group
*
grp
);
void
sysfs_unmerge_group
(
struct
kobject
*
kobj
,
const
struct
attribute_group
*
grp
);
int
sysfs_add_link_to_group
(
struct
kobject
*
kobj
,
const
char
*
group_name
,
struct
kobject
*
target
,
const
char
*
link_name
);
void
sysfs_remove_link_from_group
(
struct
kobject
*
kobj
,
const
char
*
group_name
,
const
char
*
link_name
);
void
sysfs_notify
(
struct
kobject
*
kobj
,
const
char
*
dir
,
const
char
*
attr
);
void
sysfs_notify_dirent
(
struct
sysfs_dirent
*
sd
);
...
...
@@ -326,6 +330,18 @@ static inline void sysfs_unmerge_group(struct kobject *kobj,
{
}
static
inline
int
sysfs_add_link_to_group
(
struct
kobject
*
kobj
,
const
char
*
group_name
,
struct
kobject
*
target
,
const
char
*
link_name
)
{
return
0
;
}
static
inline
void
sysfs_remove_link_from_group
(
struct
kobject
*
kobj
,
const
char
*
group_name
,
const
char
*
link_name
)
{
}
static
inline
void
sysfs_notify
(
struct
kobject
*
kobj
,
const
char
*
dir
,
const
char
*
attr
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录