Skip to content

Commit 3f491a2

Browse files
committed
Merge back ACPI power management material for v5.14.
2 parents f1ffa9d + 6381195 commit 3f491a2

File tree

8 files changed

+79
-71
lines changed

8 files changed

+79
-71
lines changed

drivers/acpi/device_pm.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <linux/pm_runtime.h>
2121
#include <linux/suspend.h>
2222

23+
#include "fan.h"
2324
#include "internal.h"
2425

2526
/**
@@ -1310,10 +1311,7 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on)
13101311
* with the generic ACPI PM domain.
13111312
*/
13121313
static const struct acpi_device_id special_pm_ids[] = {
1313-
{"PNP0C0B", }, /* Generic ACPI fan */
1314-
{"INT3404", }, /* Fan */
1315-
{"INTC1044", }, /* Fan for Tiger Lake generation */
1316-
{"INTC1048", }, /* Fan for Alder Lake generation */
1314+
ACPI_FAN_DEVICE_IDS,
13171315
{}
13181316
};
13191317
struct acpi_device *adev = ACPI_COMPANION(dev);

drivers/acpi/fan.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include <linux/platform_device.h>
1717
#include <linux/sort.h>
1818

19+
#include "fan.h"
20+
1921
MODULE_AUTHOR("Paul Diefenbaugh");
2022
MODULE_DESCRIPTION("ACPI Fan Driver");
2123
MODULE_LICENSE("GPL");
@@ -24,10 +26,7 @@ static int acpi_fan_probe(struct platform_device *pdev);
2426
static int acpi_fan_remove(struct platform_device *pdev);
2527

2628
static const struct acpi_device_id fan_device_ids[] = {
27-
{"PNP0C0B", 0},
28-
{"INT3404", 0},
29-
{"INTC1044", 0},
30-
{"INTC1048", 0},
29+
ACPI_FAN_DEVICE_IDS,
3130
{"", 0},
3231
};
3332
MODULE_DEVICE_TABLE(acpi, fan_device_ids);

drivers/acpi/fan.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
3+
/*
4+
* ACPI fan device IDs are shared between the fan driver and the device power
5+
* management code.
6+
*
7+
* Add new device IDs before the generic ACPI fan one.
8+
*/
9+
#define ACPI_FAN_DEVICE_IDS \
10+
{"INT3404", }, /* Fan */ \
11+
{"INTC1044", }, /* Fan for Tiger Lake generation */ \
12+
{"INTC1048", }, /* Fan for Alder Lake generation */ \
13+
{"PNP0C0B", } /* Generic ACPI fan */

drivers/acpi/internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ int acpi_device_sleep_wake(struct acpi_device *dev,
142142
int acpi_power_get_inferred_state(struct acpi_device *device, int *state);
143143
int acpi_power_on_resources(struct acpi_device *device, int state);
144144
int acpi_power_transition(struct acpi_device *device, int state);
145-
void acpi_turn_off_unused_power_resources(bool init);
145+
void acpi_turn_off_unused_power_resources(void);
146146

147147
/* --------------------------------------------------------------------------
148148
Device Power Management

drivers/acpi/power.c

Lines changed: 54 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ struct acpi_power_resource {
5252
u32 system_level;
5353
u32 order;
5454
unsigned int ref_count;
55-
unsigned int users;
55+
u8 state;
5656
bool wakeup_enabled;
5757
struct mutex resource_lock;
5858
struct list_head dependents;
@@ -173,53 +173,61 @@ int acpi_extract_power_resources(union acpi_object *package, unsigned int start,
173173
err = acpi_power_resources_list_add(rhandle, list);
174174
if (err)
175175
break;
176-
177-
to_power_resource(rdev)->users++;
178176
}
179177
if (err)
180178
acpi_power_resources_list_free(list);
181179

182180
return err;
183181
}
184182

185-
static int acpi_power_get_state(acpi_handle handle, int *state)
183+
static int __get_state(acpi_handle handle, u8 *state)
186184
{
187185
acpi_status status = AE_OK;
188186
unsigned long long sta = 0;
189-
190-
if (!handle || !state)
191-
return -EINVAL;
187+
u8 cur_state;
192188

193189
status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
194190
if (ACPI_FAILURE(status))
195191
return -ENODEV;
196192

197-
*state = (sta & 0x01)?ACPI_POWER_RESOURCE_STATE_ON:
198-
ACPI_POWER_RESOURCE_STATE_OFF;
193+
cur_state = sta & ACPI_POWER_RESOURCE_STATE_ON;
199194

200195
acpi_handle_debug(handle, "Power resource is %s\n",
201-
*state ? "on" : "off");
196+
cur_state ? "on" : "off");
197+
198+
*state = cur_state;
199+
return 0;
200+
}
201+
202+
static int acpi_power_get_state(struct acpi_power_resource *resource, u8 *state)
203+
{
204+
if (resource->state == ACPI_POWER_RESOURCE_STATE_UNKNOWN) {
205+
int ret;
202206

207+
ret = __get_state(resource->device.handle, &resource->state);
208+
if (ret)
209+
return ret;
210+
}
211+
212+
*state = resource->state;
203213
return 0;
204214
}
205215

206-
static int acpi_power_get_list_state(struct list_head *list, int *state)
216+
static int acpi_power_get_list_state(struct list_head *list, u8 *state)
207217
{
208218
struct acpi_power_resource_entry *entry;
209-
int cur_state;
219+
u8 cur_state = ACPI_POWER_RESOURCE_STATE_OFF;
210220

211221
if (!list || !state)
212222
return -EINVAL;
213223

214224
/* The state of the list is 'on' IFF all resources are 'on'. */
215-
cur_state = 0;
216225
list_for_each_entry(entry, list, node) {
217226
struct acpi_power_resource *resource = entry->resource;
218-
acpi_handle handle = resource->device.handle;
219227
int result;
220228

221229
mutex_lock(&resource->resource_lock);
222-
result = acpi_power_get_state(handle, &cur_state);
230+
result = acpi_power_get_state(resource, &cur_state);
223231
mutex_unlock(&resource->resource_lock);
224232
if (result)
225233
return result;
@@ -352,8 +360,12 @@ static int __acpi_power_on(struct acpi_power_resource *resource)
352360
acpi_status status = AE_OK;
353361

354362
status = acpi_evaluate_object(resource->device.handle, "_ON", NULL, NULL);
355-
if (ACPI_FAILURE(status))
363+
if (ACPI_FAILURE(status)) {
364+
resource->state = ACPI_POWER_RESOURCE_STATE_UNKNOWN;
356365
return -ENODEV;
366+
}
367+
368+
resource->state = ACPI_POWER_RESOURCE_STATE_ON;
357369

358370
pr_debug("Power resource [%s] turned on\n", resource->name);
359371

@@ -405,8 +417,12 @@ static int __acpi_power_off(struct acpi_power_resource *resource)
405417

406418
status = acpi_evaluate_object(resource->device.handle, "_OFF",
407419
NULL, NULL);
408-
if (ACPI_FAILURE(status))
420+
if (ACPI_FAILURE(status)) {
421+
resource->state = ACPI_POWER_RESOURCE_STATE_UNKNOWN;
409422
return -ENODEV;
423+
}
424+
425+
resource->state = ACPI_POWER_RESOURCE_STATE_OFF;
410426

411427
pr_debug("Power resource [%s] turned off\n", resource->name);
412428

@@ -590,13 +606,12 @@ int acpi_power_wakeup_list_init(struct list_head *list, int *system_level_p)
590606

591607
list_for_each_entry(entry, list, node) {
592608
struct acpi_power_resource *resource = entry->resource;
593-
acpi_handle handle = resource->device.handle;
594609
int result;
595-
int state;
610+
u8 state;
596611

597612
mutex_lock(&resource->resource_lock);
598613

599-
result = acpi_power_get_state(handle, &state);
614+
result = acpi_power_get_state(resource, &state);
600615
if (result) {
601616
mutex_unlock(&resource->resource_lock);
602617
return result;
@@ -789,8 +804,8 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev)
789804

790805
int acpi_power_get_inferred_state(struct acpi_device *device, int *state)
791806
{
807+
u8 list_state = ACPI_POWER_RESOURCE_STATE_OFF;
792808
int result = 0;
793-
int list_state = 0;
794809
int i = 0;
795810

796811
if (!device || !state)
@@ -919,7 +934,7 @@ struct acpi_device *acpi_add_power_resource(acpi_handle handle)
919934
union acpi_object acpi_object;
920935
struct acpi_buffer buffer = { sizeof(acpi_object), &acpi_object };
921936
acpi_status status;
922-
int state, result = -ENODEV;
937+
int result;
923938

924939
acpi_bus_get_device(handle, &device);
925940
if (device)
@@ -946,13 +961,9 @@ struct acpi_device *acpi_add_power_resource(acpi_handle handle)
946961

947962
resource->system_level = acpi_object.power_resource.system_level;
948963
resource->order = acpi_object.power_resource.resource_order;
964+
resource->state = ACPI_POWER_RESOURCE_STATE_UNKNOWN;
949965

950-
result = acpi_power_get_state(handle, &state);
951-
if (result)
952-
goto err;
953-
954-
pr_info("%s [%s] (%s)\n", acpi_device_name(device),
955-
acpi_device_bid(device), state ? "on" : "off");
966+
pr_info("%s [%s]\n", acpi_device_name(device), acpi_device_bid(device));
956967

957968
device->flags.match_driver = true;
958969
result = acpi_device_add(device, acpi_release_power_resource);
@@ -979,11 +990,13 @@ void acpi_resume_power_resources(void)
979990
mutex_lock(&power_resource_list_lock);
980991

981992
list_for_each_entry(resource, &acpi_power_resource_list, list_node) {
982-
int result, state;
993+
int result;
994+
u8 state;
983995

984996
mutex_lock(&resource->resource_lock);
985997

986-
result = acpi_power_get_state(resource->device.handle, &state);
998+
resource->state = ACPI_POWER_RESOURCE_STATE_UNKNOWN;
999+
result = acpi_power_get_state(resource, &state);
9871000
if (result) {
9881001
mutex_unlock(&resource->resource_lock);
9891002
continue;
@@ -1002,38 +1015,10 @@ void acpi_resume_power_resources(void)
10021015
}
10031016
#endif
10041017

1005-
static void acpi_power_turn_off_if_unused(struct acpi_power_resource *resource,
1006-
bool init)
1007-
{
1008-
if (resource->ref_count > 0)
1009-
return;
1010-
1011-
if (init) {
1012-
if (resource->users > 0)
1013-
return;
1014-
} else {
1015-
int result, state;
1016-
1017-
result = acpi_power_get_state(resource->device.handle, &state);
1018-
if (result || state == ACPI_POWER_RESOURCE_STATE_OFF)
1019-
return;
1020-
}
1021-
1022-
dev_info(&resource->device.dev, "Turning OFF\n");
1023-
__acpi_power_off(resource);
1024-
}
1025-
10261018
/**
10271019
* acpi_turn_off_unused_power_resources - Turn off power resources not in use.
1028-
* @init: Control switch.
1029-
*
1030-
* If @ainit is set, unconditionally turn off all of the ACPI power resources
1031-
* without any users.
1032-
*
1033-
* Otherwise, turn off all ACPI power resources without active references (that
1034-
* is, the ones that should be "off" at the moment) that are "on".
10351020
*/
1036-
void acpi_turn_off_unused_power_resources(bool init)
1021+
void acpi_turn_off_unused_power_resources(void)
10371022
{
10381023
struct acpi_power_resource *resource;
10391024

@@ -1042,7 +1027,16 @@ void acpi_turn_off_unused_power_resources(bool init)
10421027
list_for_each_entry_reverse(resource, &acpi_power_resource_list, list_node) {
10431028
mutex_lock(&resource->resource_lock);
10441029

1045-
acpi_power_turn_off_if_unused(resource, init);
1030+
/*
1031+
* Turn off power resources in an unknown state too, because the
1032+
* platform firmware on some system expects the OS to turn off
1033+
* power resources without any users unconditionally.
1034+
*/
1035+
if (!resource->ref_count &&
1036+
resource->state != ACPI_POWER_RESOURCE_STATE_OFF) {
1037+
dev_info(&resource->device.dev, "Turning OFF\n");
1038+
__acpi_power_off(resource);
1039+
}
10461040

10471041
mutex_unlock(&resource->resource_lock);
10481042
}

drivers/acpi/scan.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2360,7 +2360,7 @@ int __init acpi_scan_init(void)
23602360
}
23612361
}
23622362

2363-
acpi_turn_off_unused_power_resources(true);
2363+
acpi_turn_off_unused_power_resources();
23642364

23652365
acpi_scan_initialized = true;
23662366

drivers/acpi/sleep.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ static void acpi_pm_start(u32 acpi_state)
504504
*/
505505
static void acpi_pm_end(void)
506506
{
507-
acpi_turn_off_unused_power_resources(false);
507+
acpi_turn_off_unused_power_resources();
508508
acpi_scan_lock_release();
509509
/*
510510
* This is necessary in case acpi_pm_finish() is not called during a

drivers/acpi/x86/s2idle.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ static const struct acpi_device_id lps0_device_ids[] = {
4242

4343
/* AMD */
4444
#define ACPI_LPS0_DSM_UUID_AMD "e3f32452-febc-43ce-9039-932122d37721"
45+
#define ACPI_LPS0_ENTRY_AMD 2
46+
#define ACPI_LPS0_EXIT_AMD 3
4547
#define ACPI_LPS0_SCREEN_OFF_AMD 4
4648
#define ACPI_LPS0_SCREEN_ON_AMD 5
4749

@@ -408,6 +410,7 @@ int acpi_s2idle_prepare_late(void)
408410

409411
if (acpi_s2idle_vendor_amd()) {
410412
acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF_AMD);
413+
acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY_AMD);
411414
} else {
412415
acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF);
413416
acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY);
@@ -422,6 +425,7 @@ void acpi_s2idle_restore_early(void)
422425
return;
423426

424427
if (acpi_s2idle_vendor_amd()) {
428+
acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT_AMD);
425429
acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON_AMD);
426430
} else {
427431
acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT);

0 commit comments

Comments
 (0)