Skip to content

Commit f8df160

Browse files
committed
Merge branches 'acpi-pm', 'acpi-battery' and 'acpi-ac'
Merge updates related to device power management, system sleep, battery driver and AC driver for 5.16-rc1: - Check the states of all ACPI power resources during initialization to avoid dealing with power resources in unknown states (Rafael Wysocki). - Fix ACPI power resource issues related to sharing wakeup power resources (Rafael Wysocki). - Avoid registering redundant suspend_ops (Rafael Wysocki). - Report battery charging state as "full" if it appears to be over the design capacity (André Almeida). - Quirk GK45 mini PC to skip reading _PSR in the AC driver (Stefan Schaeckeler). * acpi-pm: ACPI: PM: sleep: Do not set suspend_ops unnecessarily ACPI: PM: Turn off wakeup power resources on _DSW/_PSW errors ACPI: PM: Fix sharing of wakeup power resources ACPI: PM: Turn off unused wakeup power resources ACPI: PM: Check states of power resources during initialization * acpi-battery: ACPI: battery: Accept charges over the design capacity as full * acpi-ac: ACPI: AC: Quirk GK45 to skip reading _PSR
4 parents c3fb466 + d69d1f7 + 2835f32 + 3d730ee commit f8df160

File tree

4 files changed

+68
-60
lines changed

4 files changed

+68
-60
lines changed

drivers/acpi/ac.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume);
6161

6262
static int ac_sleep_before_get_state_ms;
6363
static int ac_check_pmic = 1;
64+
static int ac_only;
6465

6566
static struct acpi_driver acpi_ac_driver = {
6667
.name = "ac",
@@ -93,6 +94,11 @@ static int acpi_ac_get_state(struct acpi_ac *ac)
9394
if (!ac)
9495
return -EINVAL;
9596

97+
if (ac_only) {
98+
ac->state = 1;
99+
return 0;
100+
}
101+
96102
status = acpi_evaluate_integer(ac->device->handle, "_PSR", NULL,
97103
&ac->state);
98104
if (ACPI_FAILURE(status)) {
@@ -200,6 +206,12 @@ static int __init ac_do_not_check_pmic_quirk(const struct dmi_system_id *d)
200206
return 0;
201207
}
202208

209+
static int __init ac_only_quirk(const struct dmi_system_id *d)
210+
{
211+
ac_only = 1;
212+
return 0;
213+
}
214+
203215
/* Please keep this list alphabetically sorted */
204216
static const struct dmi_system_id ac_dmi_table[] __initconst = {
205217
{
@@ -209,6 +221,13 @@ static const struct dmi_system_id ac_dmi_table[] __initconst = {
209221
DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"),
210222
},
211223
},
224+
{
225+
/* Kodlix GK45 returning incorrect state */
226+
.callback = ac_only_quirk,
227+
.matches = {
228+
DMI_MATCH(DMI_PRODUCT_NAME, "GK45"),
229+
},
230+
},
212231
{
213232
/* Lenovo Ideapad Miix 320, AXP288 PMIC, separate fuel-gauge */
214233
.callback = ac_do_not_check_pmic_quirk,

drivers/acpi/battery.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ static int acpi_battery_is_charged(struct acpi_battery *battery)
169169
return 1;
170170

171171
/* fallback to using design values for broken batteries */
172-
if (battery->design_capacity == battery->capacity_now)
172+
if (battery->design_capacity <= battery->capacity_now)
173173
return 1;
174174

175175
/* we don't do any sort of metric based on percentages */

drivers/acpi/power.c

Lines changed: 41 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ struct acpi_power_resource {
5252
u32 order;
5353
unsigned int ref_count;
5454
u8 state;
55-
bool wakeup_enabled;
5655
struct mutex resource_lock;
5756
struct list_head dependents;
5857
};
@@ -615,20 +614,19 @@ int acpi_power_wakeup_list_init(struct list_head *list, int *system_level_p)
615614

616615
list_for_each_entry(entry, list, node) {
617616
struct acpi_power_resource *resource = entry->resource;
618-
int result;
619617
u8 state;
620618

621619
mutex_lock(&resource->resource_lock);
622620

623-
result = acpi_power_get_state(resource, &state);
624-
if (result) {
625-
mutex_unlock(&resource->resource_lock);
626-
return result;
627-
}
628-
if (state == ACPI_POWER_RESOURCE_STATE_ON) {
629-
resource->ref_count++;
630-
resource->wakeup_enabled = true;
631-
}
621+
/*
622+
* Make sure that the power resource state and its reference
623+
* counter value are consistent with each other.
624+
*/
625+
if (!resource->ref_count &&
626+
!acpi_power_get_state(resource, &state) &&
627+
state == ACPI_POWER_RESOURCE_STATE_ON)
628+
__acpi_power_off(resource);
629+
632630
if (system_level > resource->system_level)
633631
system_level = resource->system_level;
634632

@@ -711,7 +709,6 @@ int acpi_device_sleep_wake(struct acpi_device *dev,
711709
*/
712710
int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
713711
{
714-
struct acpi_power_resource_entry *entry;
715712
int err = 0;
716713

717714
if (!dev || !dev->wakeup.flags.valid)
@@ -722,33 +719,22 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
722719
if (dev->wakeup.prepare_count++)
723720
goto out;
724721

725-
list_for_each_entry(entry, &dev->wakeup.resources, node) {
726-
struct acpi_power_resource *resource = entry->resource;
727-
728-
mutex_lock(&resource->resource_lock);
729-
730-
if (!resource->wakeup_enabled) {
731-
err = acpi_power_on_unlocked(resource);
732-
if (!err)
733-
resource->wakeup_enabled = true;
734-
}
735-
736-
mutex_unlock(&resource->resource_lock);
737-
738-
if (err) {
739-
dev_err(&dev->dev,
740-
"Cannot turn wakeup power resources on\n");
741-
dev->wakeup.flags.valid = 0;
742-
goto out;
743-
}
722+
err = acpi_power_on_list(&dev->wakeup.resources);
723+
if (err) {
724+
dev_err(&dev->dev, "Cannot turn on wakeup power resources\n");
725+
dev->wakeup.flags.valid = 0;
726+
goto out;
744727
}
728+
745729
/*
746730
* Passing 3 as the third argument below means the device may be
747731
* put into arbitrary power state afterward.
748732
*/
749733
err = acpi_device_sleep_wake(dev, 1, sleep_state, 3);
750-
if (err)
734+
if (err) {
735+
acpi_power_off_list(&dev->wakeup.resources);
751736
dev->wakeup.prepare_count = 0;
737+
}
752738

753739
out:
754740
mutex_unlock(&acpi_device_lock);
@@ -771,39 +757,33 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev)
771757

772758
mutex_lock(&acpi_device_lock);
773759

774-
if (--dev->wakeup.prepare_count > 0)
760+
if (dev->wakeup.prepare_count > 1) {
761+
dev->wakeup.prepare_count--;
775762
goto out;
763+
}
776764

777-
/*
778-
* Executing the code below even if prepare_count is already zero when
779-
* the function is called may be useful, for example for initialisation.
780-
*/
781-
if (dev->wakeup.prepare_count < 0)
782-
dev->wakeup.prepare_count = 0;
765+
/* Do nothing if wakeup power has not been enabled for this device. */
766+
if (!dev->wakeup.prepare_count)
767+
goto out;
783768

784769
err = acpi_device_sleep_wake(dev, 0, 0, 0);
785770
if (err)
786771
goto out;
787772

773+
/*
774+
* All of the power resources in the list need to be turned off even if
775+
* there are errors.
776+
*/
788777
list_for_each_entry(entry, &dev->wakeup.resources, node) {
789-
struct acpi_power_resource *resource = entry->resource;
790-
791-
mutex_lock(&resource->resource_lock);
792-
793-
if (resource->wakeup_enabled) {
794-
err = acpi_power_off_unlocked(resource);
795-
if (!err)
796-
resource->wakeup_enabled = false;
797-
}
798-
799-
mutex_unlock(&resource->resource_lock);
778+
int ret;
800779

801-
if (err) {
802-
dev_err(&dev->dev,
803-
"Cannot turn wakeup power resources off\n");
804-
dev->wakeup.flags.valid = 0;
805-
break;
806-
}
780+
ret = acpi_power_off(entry->resource);
781+
if (ret && !err)
782+
err = ret;
783+
}
784+
if (err) {
785+
dev_err(&dev->dev, "Cannot turn off wakeup power resources\n");
786+
dev->wakeup.flags.valid = 0;
807787
}
808788

809789
out:
@@ -943,6 +923,7 @@ struct acpi_device *acpi_add_power_resource(acpi_handle handle)
943923
union acpi_object acpi_object;
944924
struct acpi_buffer buffer = { sizeof(acpi_object), &acpi_object };
945925
acpi_status status;
926+
u8 state_dummy;
946927
int result;
947928

948929
acpi_bus_get_device(handle, &device);
@@ -971,6 +952,10 @@ struct acpi_device *acpi_add_power_resource(acpi_handle handle)
971952
resource->order = acpi_object.power_resource.resource_order;
972953
resource->state = ACPI_POWER_RESOURCE_STATE_UNKNOWN;
973954

955+
/* Get the initial state or just flip it on if that fails. */
956+
if (acpi_power_get_state(resource, &state_dummy))
957+
__acpi_power_on(resource);
958+
974959
pr_info("%s [%s]\n", acpi_device_name(device), acpi_device_bid(device));
975960

976961
device->flags.match_driver = true;

drivers/acpi/sleep.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -815,14 +815,18 @@ void __weak acpi_s2idle_setup(void)
815815

816816
static void acpi_sleep_suspend_setup(void)
817817
{
818+
bool suspend_ops_needed = false;
818819
int i;
819820

820821
for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++)
821-
if (acpi_sleep_state_supported(i))
822+
if (acpi_sleep_state_supported(i)) {
822823
sleep_states[i] = 1;
824+
suspend_ops_needed = true;
825+
}
823826

824-
suspend_set_ops(old_suspend_ordering ?
825-
&acpi_suspend_ops_old : &acpi_suspend_ops);
827+
if (suspend_ops_needed)
828+
suspend_set_ops(old_suspend_ordering ?
829+
&acpi_suspend_ops_old : &acpi_suspend_ops);
826830

827831
acpi_s2idle_setup();
828832
}

0 commit comments

Comments
 (0)