Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
3f491a28
Commit
3f491a28
authored
Jun 14, 2021
by
Rafael J. Wysocki
Browse files
Options
Browse Files
Download
Plain Diff
Merge back ACPI power management material for v5.14.
parents
f1ffa9d4
6381195a
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
79 additions
and
71 deletions
+79
-71
drivers/acpi/device_pm.c
drivers/acpi/device_pm.c
+2
-4
drivers/acpi/fan.c
drivers/acpi/fan.c
+3
-4
drivers/acpi/fan.h
drivers/acpi/fan.h
+13
-0
drivers/acpi/internal.h
drivers/acpi/internal.h
+1
-1
drivers/acpi/power.c
drivers/acpi/power.c
+54
-60
drivers/acpi/scan.c
drivers/acpi/scan.c
+1
-1
drivers/acpi/sleep.c
drivers/acpi/sleep.c
+1
-1
drivers/acpi/x86/s2idle.c
drivers/acpi/x86/s2idle.c
+4
-0
No files found.
drivers/acpi/device_pm.c
View file @
3f491a28
...
...
@@ -20,6 +20,7 @@
#include <linux/pm_runtime.h>
#include <linux/suspend.h>
#include "fan.h"
#include "internal.h"
/**
...
...
@@ -1310,10 +1311,7 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on)
* with the generic ACPI PM domain.
*/
static
const
struct
acpi_device_id
special_pm_ids
[]
=
{
{
"PNP0C0B"
,
},
/* Generic ACPI fan */
{
"INT3404"
,
},
/* Fan */
{
"INTC1044"
,
},
/* Fan for Tiger Lake generation */
{
"INTC1048"
,
},
/* Fan for Alder Lake generation */
ACPI_FAN_DEVICE_IDS
,
{}
};
struct
acpi_device
*
adev
=
ACPI_COMPANION
(
dev
);
...
...
drivers/acpi/fan.c
View file @
3f491a28
...
...
@@ -16,6 +16,8 @@
#include <linux/platform_device.h>
#include <linux/sort.h>
#include "fan.h"
MODULE_AUTHOR
(
"Paul Diefenbaugh"
);
MODULE_DESCRIPTION
(
"ACPI Fan Driver"
);
MODULE_LICENSE
(
"GPL"
);
...
...
@@ -24,10 +26,7 @@ static int acpi_fan_probe(struct platform_device *pdev);
static
int
acpi_fan_remove
(
struct
platform_device
*
pdev
);
static
const
struct
acpi_device_id
fan_device_ids
[]
=
{
{
"PNP0C0B"
,
0
},
{
"INT3404"
,
0
},
{
"INTC1044"
,
0
},
{
"INTC1048"
,
0
},
ACPI_FAN_DEVICE_IDS
,
{
""
,
0
},
};
MODULE_DEVICE_TABLE
(
acpi
,
fan_device_ids
);
...
...
drivers/acpi/fan.h
0 → 100644
View file @
3f491a28
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* ACPI fan device IDs are shared between the fan driver and the device power
* management code.
*
* Add new device IDs before the generic ACPI fan one.
*/
#define ACPI_FAN_DEVICE_IDS \
{"INT3404", },
/* Fan */
\
{"INTC1044", },
/* Fan for Tiger Lake generation */
\
{"INTC1048", },
/* Fan for Alder Lake generation */
\
{"PNP0C0B", }
/* Generic ACPI fan */
drivers/acpi/internal.h
View file @
3f491a28
...
...
@@ -142,7 +142,7 @@ int acpi_device_sleep_wake(struct acpi_device *dev,
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
);
void
acpi_turn_off_unused_power_resources
(
bool
init
);
void
acpi_turn_off_unused_power_resources
(
void
);
/* --------------------------------------------------------------------------
Device Power Management
...
...
drivers/acpi/power.c
View file @
3f491a28
...
...
@@ -52,7 +52,7 @@ struct acpi_power_resource {
u32
system_level
;
u32
order
;
unsigned
int
ref_count
;
u
nsigned
int
users
;
u
8
state
;
bool
wakeup_enabled
;
struct
mutex
resource_lock
;
struct
list_head
dependents
;
...
...
@@ -173,8 +173,6 @@ int acpi_extract_power_resources(union acpi_object *package, unsigned int start,
err
=
acpi_power_resources_list_add
(
rhandle
,
list
);
if
(
err
)
break
;
to_power_resource
(
rdev
)
->
users
++
;
}
if
(
err
)
acpi_power_resources_list_free
(
list
);
...
...
@@ -182,44 +180,54 @@ int acpi_extract_power_resources(union acpi_object *package, unsigned int start,
return
err
;
}
static
int
acpi_power_get_state
(
acpi_handle
handle
,
int
*
state
)
static
int
__get_state
(
acpi_handle
handle
,
u8
*
state
)
{
acpi_status
status
=
AE_OK
;
unsigned
long
long
sta
=
0
;
if
(
!
handle
||
!
state
)
return
-
EINVAL
;
u8
cur_state
;
status
=
acpi_evaluate_integer
(
handle
,
"_STA"
,
NULL
,
&
sta
);
if
(
ACPI_FAILURE
(
status
))
return
-
ENODEV
;
*
state
=
(
sta
&
0x01
)
?
ACPI_POWER_RESOURCE_STATE_ON
:
ACPI_POWER_RESOURCE_STATE_OFF
;
cur_state
=
sta
&
ACPI_POWER_RESOURCE_STATE_ON
;
acpi_handle_debug
(
handle
,
"Power resource is %s
\n
"
,
*
state
?
"on"
:
"off"
);
cur_state
?
"on"
:
"off"
);
*
state
=
cur_state
;
return
0
;
}
static
int
acpi_power_get_state
(
struct
acpi_power_resource
*
resource
,
u8
*
state
)
{
if
(
resource
->
state
==
ACPI_POWER_RESOURCE_STATE_UNKNOWN
)
{
int
ret
;
ret
=
__get_state
(
resource
->
device
.
handle
,
&
resource
->
state
);
if
(
ret
)
return
ret
;
}
*
state
=
resource
->
state
;
return
0
;
}
static
int
acpi_power_get_list_state
(
struct
list_head
*
list
,
int
*
state
)
static
int
acpi_power_get_list_state
(
struct
list_head
*
list
,
u8
*
state
)
{
struct
acpi_power_resource_entry
*
entry
;
int
cur_state
;
u8
cur_state
=
ACPI_POWER_RESOURCE_STATE_OFF
;
if
(
!
list
||
!
state
)
return
-
EINVAL
;
/* The state of the list is 'on' IFF all resources are 'on'. */
cur_state
=
0
;
list_for_each_entry
(
entry
,
list
,
node
)
{
struct
acpi_power_resource
*
resource
=
entry
->
resource
;
acpi_handle
handle
=
resource
->
device
.
handle
;
int
result
;
mutex_lock
(
&
resource
->
resource_lock
);
result
=
acpi_power_get_state
(
handl
e
,
&
cur_state
);
result
=
acpi_power_get_state
(
resourc
e
,
&
cur_state
);
mutex_unlock
(
&
resource
->
resource_lock
);
if
(
result
)
return
result
;
...
...
@@ -352,8 +360,12 @@ static int __acpi_power_on(struct acpi_power_resource *resource)
acpi_status
status
=
AE_OK
;
status
=
acpi_evaluate_object
(
resource
->
device
.
handle
,
"_ON"
,
NULL
,
NULL
);
if
(
ACPI_FAILURE
(
status
))
if
(
ACPI_FAILURE
(
status
))
{
resource
->
state
=
ACPI_POWER_RESOURCE_STATE_UNKNOWN
;
return
-
ENODEV
;
}
resource
->
state
=
ACPI_POWER_RESOURCE_STATE_ON
;
pr_debug
(
"Power resource [%s] turned on
\n
"
,
resource
->
name
);
...
...
@@ -405,8 +417,12 @@ static int __acpi_power_off(struct acpi_power_resource *resource)
status
=
acpi_evaluate_object
(
resource
->
device
.
handle
,
"_OFF"
,
NULL
,
NULL
);
if
(
ACPI_FAILURE
(
status
))
if
(
ACPI_FAILURE
(
status
))
{
resource
->
state
=
ACPI_POWER_RESOURCE_STATE_UNKNOWN
;
return
-
ENODEV
;
}
resource
->
state
=
ACPI_POWER_RESOURCE_STATE_OFF
;
pr_debug
(
"Power resource [%s] turned off
\n
"
,
resource
->
name
);
...
...
@@ -590,13 +606,12 @@ int acpi_power_wakeup_list_init(struct list_head *list, int *system_level_p)
list_for_each_entry
(
entry
,
list
,
node
)
{
struct
acpi_power_resource
*
resource
=
entry
->
resource
;
acpi_handle
handle
=
resource
->
device
.
handle
;
int
result
;
int
state
;
u8
state
;
mutex_lock
(
&
resource
->
resource_lock
);
result
=
acpi_power_get_state
(
handl
e
,
&
state
);
result
=
acpi_power_get_state
(
resourc
e
,
&
state
);
if
(
result
)
{
mutex_unlock
(
&
resource
->
resource_lock
);
return
result
;
...
...
@@ -789,8 +804,8 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev)
int
acpi_power_get_inferred_state
(
struct
acpi_device
*
device
,
int
*
state
)
{
u8
list_state
=
ACPI_POWER_RESOURCE_STATE_OFF
;
int
result
=
0
;
int
list_state
=
0
;
int
i
=
0
;
if
(
!
device
||
!
state
)
...
...
@@ -919,7 +934,7 @@ struct acpi_device *acpi_add_power_resource(acpi_handle handle)
union
acpi_object
acpi_object
;
struct
acpi_buffer
buffer
=
{
sizeof
(
acpi_object
),
&
acpi_object
};
acpi_status
status
;
int
state
,
result
=
-
ENODEV
;
int
result
;
acpi_bus_get_device
(
handle
,
&
device
);
if
(
device
)
...
...
@@ -946,13 +961,9 @@ struct acpi_device *acpi_add_power_resource(acpi_handle handle)
resource
->
system_level
=
acpi_object
.
power_resource
.
system_level
;
resource
->
order
=
acpi_object
.
power_resource
.
resource_order
;
resource
->
state
=
ACPI_POWER_RESOURCE_STATE_UNKNOWN
;
result
=
acpi_power_get_state
(
handle
,
&
state
);
if
(
result
)
goto
err
;
pr_info
(
"%s [%s] (%s)
\n
"
,
acpi_device_name
(
device
),
acpi_device_bid
(
device
),
state
?
"on"
:
"off"
);
pr_info
(
"%s [%s]
\n
"
,
acpi_device_name
(
device
),
acpi_device_bid
(
device
));
device
->
flags
.
match_driver
=
true
;
result
=
acpi_device_add
(
device
,
acpi_release_power_resource
);
...
...
@@ -979,11 +990,13 @@ void acpi_resume_power_resources(void)
mutex_lock
(
&
power_resource_list_lock
);
list_for_each_entry
(
resource
,
&
acpi_power_resource_list
,
list_node
)
{
int
result
,
state
;
int
result
;
u8
state
;
mutex_lock
(
&
resource
->
resource_lock
);
result
=
acpi_power_get_state
(
resource
->
device
.
handle
,
&
state
);
resource
->
state
=
ACPI_POWER_RESOURCE_STATE_UNKNOWN
;
result
=
acpi_power_get_state
(
resource
,
&
state
);
if
(
result
)
{
mutex_unlock
(
&
resource
->
resource_lock
);
continue
;
...
...
@@ -1002,38 +1015,10 @@ void acpi_resume_power_resources(void)
}
#endif
static
void
acpi_power_turn_off_if_unused
(
struct
acpi_power_resource
*
resource
,
bool
init
)
{
if
(
resource
->
ref_count
>
0
)
return
;
if
(
init
)
{
if
(
resource
->
users
>
0
)
return
;
}
else
{
int
result
,
state
;
result
=
acpi_power_get_state
(
resource
->
device
.
handle
,
&
state
);
if
(
result
||
state
==
ACPI_POWER_RESOURCE_STATE_OFF
)
return
;
}
dev_info
(
&
resource
->
device
.
dev
,
"Turning OFF
\n
"
);
__acpi_power_off
(
resource
);
}
/**
* acpi_turn_off_unused_power_resources - Turn off power resources not in use.
* @init: Control switch.
*
* If @ainit is set, unconditionally turn off all of the ACPI power resources
* without any users.
*
* Otherwise, turn off all ACPI power resources without active references (that
* is, the ones that should be "off" at the moment) that are "on".
*/
void
acpi_turn_off_unused_power_resources
(
bool
init
)
void
acpi_turn_off_unused_power_resources
(
void
)
{
struct
acpi_power_resource
*
resource
;
...
...
@@ -1042,7 +1027,16 @@ void acpi_turn_off_unused_power_resources(bool init)
list_for_each_entry_reverse
(
resource
,
&
acpi_power_resource_list
,
list_node
)
{
mutex_lock
(
&
resource
->
resource_lock
);
acpi_power_turn_off_if_unused
(
resource
,
init
);
/*
* Turn off power resources in an unknown state too, because the
* platform firmware on some system expects the OS to turn off
* power resources without any users unconditionally.
*/
if
(
!
resource
->
ref_count
&&
resource
->
state
!=
ACPI_POWER_RESOURCE_STATE_OFF
)
{
dev_info
(
&
resource
->
device
.
dev
,
"Turning OFF
\n
"
);
__acpi_power_off
(
resource
);
}
mutex_unlock
(
&
resource
->
resource_lock
);
}
...
...
drivers/acpi/scan.c
View file @
3f491a28
...
...
@@ -2360,7 +2360,7 @@ int __init acpi_scan_init(void)
}
}
acpi_turn_off_unused_power_resources
(
true
);
acpi_turn_off_unused_power_resources
();
acpi_scan_initialized
=
true
;
...
...
drivers/acpi/sleep.c
View file @
3f491a28
...
...
@@ -504,7 +504,7 @@ static void acpi_pm_start(u32 acpi_state)
*/
static
void
acpi_pm_end
(
void
)
{
acpi_turn_off_unused_power_resources
(
false
);
acpi_turn_off_unused_power_resources
();
acpi_scan_lock_release
();
/*
* This is necessary in case acpi_pm_finish() is not called during a
...
...
drivers/acpi/x86/s2idle.c
View file @
3f491a28
...
...
@@ -42,6 +42,8 @@ static const struct acpi_device_id lps0_device_ids[] = {
/* AMD */
#define ACPI_LPS0_DSM_UUID_AMD "e3f32452-febc-43ce-9039-932122d37721"
#define ACPI_LPS0_ENTRY_AMD 2
#define ACPI_LPS0_EXIT_AMD 3
#define ACPI_LPS0_SCREEN_OFF_AMD 4
#define ACPI_LPS0_SCREEN_ON_AMD 5
...
...
@@ -408,6 +410,7 @@ int acpi_s2idle_prepare_late(void)
if
(
acpi_s2idle_vendor_amd
())
{
acpi_sleep_run_lps0_dsm
(
ACPI_LPS0_SCREEN_OFF_AMD
);
acpi_sleep_run_lps0_dsm
(
ACPI_LPS0_ENTRY_AMD
);
}
else
{
acpi_sleep_run_lps0_dsm
(
ACPI_LPS0_SCREEN_OFF
);
acpi_sleep_run_lps0_dsm
(
ACPI_LPS0_ENTRY
);
...
...
@@ -422,6 +425,7 @@ void acpi_s2idle_restore_early(void)
return
;
if
(
acpi_s2idle_vendor_amd
())
{
acpi_sleep_run_lps0_dsm
(
ACPI_LPS0_EXIT_AMD
);
acpi_sleep_run_lps0_dsm
(
ACPI_LPS0_SCREEN_ON_AMD
);
}
else
{
acpi_sleep_run_lps0_dsm
(
ACPI_LPS0_EXIT
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment