Skip to content

Commit ada0629

Browse files
committed
Merge branches 'pm-core', 'pm-sleep', 'pm-acpi' and 'pm-domains'
* pm-core: PM: runtime: Add pm_runtime_get_if_active() * pm-sleep: PM: sleep: wakeup: Skip wakeup_source_sysfs_remove() if device is not there PM / hibernate: Remove unnecessary compat ioctl overrides PM: hibernate: fix docs for ioctls that return loff_t via pointer PM: sleep: wakeup: Use built-in RCU list checking PM: sleep: core: Use built-in RCU list checking * pm-acpi: ACPI: PM: s2idle: Refine active GPEs check ACPICA: Allow acpi_any_gpe_status_set() to skip one GPE ACPI: PM: s2idle: Fix comment in acpi_s2idle_prepare_late() * pm-domains: cpuidle: psci: Split psci_dt_cpu_init_idle() PM / Domains: Allow no domain-idle-states DT property in genpd when parsing
5 parents 0411f0d + c111566 + 87de659 + d540628 + 7fbee48 commit ada0629

File tree

16 files changed

+166
-87
lines changed

16 files changed

+166
-87
lines changed

Documentation/power/runtime_pm.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,12 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
382382
nonzero, increment the counter and return 1; otherwise return 0 without
383383
changing the counter
384384

385+
`int pm_runtime_get_if_active(struct device *dev, bool ign_usage_count);`
386+
- return -EINVAL if 'power.disable_depth' is nonzero; otherwise, if the
387+
runtime PM status is RPM_ACTIVE, and either ign_usage_count is true
388+
or the device's usage_count is non-zero, increment the counter and
389+
return 1; otherwise return 0 without changing the counter
390+
385391
`void pm_runtime_put_noidle(struct device *dev);`
386392
- decrement the device's usage counter
387393

Documentation/power/userland-swsusp.rst

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,13 @@ SNAPSHOT_PREF_IMAGE_SIZE
6969

7070
SNAPSHOT_GET_IMAGE_SIZE
7171
return the actual size of the hibernation image
72+
(the last argument should be a pointer to a loff_t variable that
73+
will contain the result if the call is successful)
7274

7375
SNAPSHOT_AVAIL_SWAP_SIZE
74-
return the amount of available swap in bytes (the
75-
last argument should be a pointer to an unsigned int variable that will
76-
contain the result if the call is successful).
76+
return the amount of available swap in bytes
77+
(the last argument should be a pointer to a loff_t variable that
78+
will contain the result if the call is successful)
7779

7880
SNAPSHOT_ALLOC_SWAP_PAGE
7981
allocate a swap page from the resume partition

drivers/acpi/acpica/achware.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ acpi_status acpi_hw_enable_all_runtime_gpes(void);
101101

102102
acpi_status acpi_hw_enable_all_wakeup_gpes(void);
103103

104-
u8 acpi_hw_check_all_gpes(void);
104+
u8 acpi_hw_check_all_gpes(acpi_handle gpe_skip_device, u32 gpe_skip_number);
105105

106106
acpi_status
107107
acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,

drivers/acpi/acpica/evxfgpe.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -799,17 +799,19 @@ ACPI_EXPORT_SYMBOL(acpi_enable_all_wakeup_gpes)
799799
*
800800
* FUNCTION: acpi_any_gpe_status_set
801801
*
802-
* PARAMETERS: None
802+
* PARAMETERS: gpe_skip_number - Number of the GPE to skip
803803
*
804804
* RETURN: Whether or not the status bit is set for any GPE
805805
*
806-
* DESCRIPTION: Check the status bits of all enabled GPEs and return TRUE if any
807-
* of them is set or FALSE otherwise.
806+
* DESCRIPTION: Check the status bits of all enabled GPEs, except for the one
807+
* represented by the "skip" argument, and return TRUE if any of
808+
* them is set or FALSE otherwise.
808809
*
809810
******************************************************************************/
810-
u32 acpi_any_gpe_status_set(void)
811+
u32 acpi_any_gpe_status_set(u32 gpe_skip_number)
811812
{
812813
acpi_status status;
814+
acpi_handle gpe_device;
813815
u8 ret;
814816

815817
ACPI_FUNCTION_TRACE(acpi_any_gpe_status_set);
@@ -819,7 +821,12 @@ u32 acpi_any_gpe_status_set(void)
819821
return (FALSE);
820822
}
821823

822-
ret = acpi_hw_check_all_gpes();
824+
status = acpi_get_gpe_device(gpe_skip_number, &gpe_device);
825+
if (ACPI_FAILURE(status)) {
826+
gpe_device = NULL;
827+
}
828+
829+
ret = acpi_hw_check_all_gpes(gpe_device, gpe_skip_number);
823830
(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
824831

825832
return (ret);

drivers/acpi/acpica/hwgpe.c

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -444,12 +444,19 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
444444
return (AE_OK);
445445
}
446446

447+
struct acpi_gpe_block_status_context {
448+
struct acpi_gpe_register_info *gpe_skip_register_info;
449+
u8 gpe_skip_mask;
450+
u8 retval;
451+
};
452+
447453
/******************************************************************************
448454
*
449455
* FUNCTION: acpi_hw_get_gpe_block_status
450456
*
451457
* PARAMETERS: gpe_xrupt_info - GPE Interrupt info
452458
* gpe_block - Gpe Block info
459+
* context - GPE list walk context data
453460
*
454461
* RETURN: Success
455462
*
@@ -460,12 +467,13 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
460467
static acpi_status
461468
acpi_hw_get_gpe_block_status(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
462469
struct acpi_gpe_block_info *gpe_block,
463-
void *ret_ptr)
470+
void *context)
464471
{
472+
struct acpi_gpe_block_status_context *c = context;
465473
struct acpi_gpe_register_info *gpe_register_info;
466474
u64 in_enable, in_status;
467475
acpi_status status;
468-
u8 *ret = ret_ptr;
476+
u8 ret_mask;
469477
u32 i;
470478

471479
/* Examine each GPE Register within the block */
@@ -485,7 +493,11 @@ acpi_hw_get_gpe_block_status(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
485493
continue;
486494
}
487495

488-
*ret |= in_enable & in_status;
496+
ret_mask = in_enable & in_status;
497+
if (ret_mask && c->gpe_skip_register_info == gpe_register_info) {
498+
ret_mask &= ~c->gpe_skip_mask;
499+
}
500+
c->retval |= ret_mask;
489501
}
490502

491503
return (AE_OK);
@@ -561,24 +573,41 @@ acpi_status acpi_hw_enable_all_wakeup_gpes(void)
561573
*
562574
* FUNCTION: acpi_hw_check_all_gpes
563575
*
564-
* PARAMETERS: None
576+
* PARAMETERS: gpe_skip_device - GPE devoce of the GPE to skip
577+
* gpe_skip_number - Number of the GPE to skip
565578
*
566579
* RETURN: Combined status of all GPEs
567580
*
568-
* DESCRIPTION: Check all enabled GPEs in all GPE blocks and return TRUE if the
581+
* DESCRIPTION: Check all enabled GPEs in all GPE blocks, except for the one
582+
* represented by the "skip" arguments, and return TRUE if the
569583
* status bit is set for at least one of them of FALSE otherwise.
570584
*
571585
******************************************************************************/
572586

573-
u8 acpi_hw_check_all_gpes(void)
587+
u8 acpi_hw_check_all_gpes(acpi_handle gpe_skip_device, u32 gpe_skip_number)
574588
{
575-
u8 ret = 0;
589+
struct acpi_gpe_block_status_context context = {
590+
.gpe_skip_register_info = NULL,
591+
.retval = 0,
592+
};
593+
struct acpi_gpe_event_info *gpe_event_info;
594+
acpi_cpu_flags flags;
576595

577596
ACPI_FUNCTION_TRACE(acpi_hw_check_all_gpes);
578597

579-
(void)acpi_ev_walk_gpe_list(acpi_hw_get_gpe_block_status, &ret);
598+
flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
599+
600+
gpe_event_info = acpi_ev_get_gpe_event_info(gpe_skip_device,
601+
gpe_skip_number);
602+
if (gpe_event_info) {
603+
context.gpe_skip_register_info = gpe_event_info->register_info;
604+
context.gpe_skip_mask = acpi_hw_get_gpe_register_bit(gpe_event_info);
605+
}
606+
607+
acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
580608

581-
return (ret != 0);
609+
(void)acpi_ev_walk_gpe_list(acpi_hw_get_gpe_block_status, &context);
610+
return (context.retval != 0);
582611
}
583612

584613
#endif /* !ACPI_REDUCED_HARDWARE */

drivers/acpi/ec.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2037,6 +2037,11 @@ void acpi_ec_set_gpe_wake_mask(u8 action)
20372037
acpi_set_gpe_wake_mask(NULL, first_ec->gpe, action);
20382038
}
20392039

2040+
bool acpi_ec_other_gpes_active(void)
2041+
{
2042+
return acpi_any_gpe_status_set(first_ec ? first_ec->gpe : U32_MAX);
2043+
}
2044+
20402045
bool acpi_ec_dispatch_gpe(void)
20412046
{
20422047
u32 ret;

drivers/acpi/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit);
202202

203203
#ifdef CONFIG_PM_SLEEP
204204
void acpi_ec_flush_work(void);
205+
bool acpi_ec_other_gpes_active(void);
205206
bool acpi_ec_dispatch_gpe(void);
206207
#endif
207208

drivers/acpi/sleep.c

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -982,10 +982,7 @@ static int acpi_s2idle_prepare_late(void)
982982

983983
static void acpi_s2idle_sync(void)
984984
{
985-
/*
986-
* The EC driver uses the system workqueue and an additional special
987-
* one, so those need to be flushed too.
988-
*/
985+
/* The EC driver uses special workqueues that need to be flushed. */
989986
acpi_ec_flush_work();
990987
acpi_os_wait_events_complete(); /* synchronize Notify handling */
991988
}
@@ -1013,18 +1010,19 @@ static bool acpi_s2idle_wake(void)
10131010
return true;
10141011

10151012
/*
1016-
* If there are no EC events to process and at least one of the
1017-
* other enabled GPEs is active, the wakeup is regarded as a
1018-
* genuine one.
1019-
*
1020-
* Note that the checks below must be carried out in this order
1021-
* to avoid returning prematurely due to a change of the EC GPE
1022-
* status bit from unset to set between the checks with the
1023-
* status bits of all the other GPEs unset.
1013+
* If the status bit is set for any enabled GPE other than the
1014+
* EC one, the wakeup is regarded as a genuine one.
10241015
*/
1025-
if (acpi_any_gpe_status_set() && !acpi_ec_dispatch_gpe())
1016+
if (acpi_ec_other_gpes_active())
10261017
return true;
10271018

1019+
/*
1020+
* If the EC GPE status bit has not been set, the wakeup is
1021+
* regarded as a spurious one.
1022+
*/
1023+
if (!acpi_ec_dispatch_gpe())
1024+
return false;
1025+
10281026
/*
10291027
* Cancel the wakeup and process all pending events in case
10301028
* there are any wakeup ones in there.

drivers/base/power/domain.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2653,7 +2653,7 @@ static int genpd_iterate_idle_states(struct device_node *dn,
26532653

26542654
ret = of_count_phandle_with_args(dn, "domain-idle-states", NULL);
26552655
if (ret <= 0)
2656-
return ret;
2656+
return ret == -ENOENT ? 0 : ret;
26572657

26582658
/* Loop over the phandles until all the requested entry is found */
26592659
of_for_each_phandle(&it, ret, dn, "domain-idle-states", NULL, 0) {

drivers/base/power/main.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@
4040

4141
typedef int (*pm_callback_t)(struct device *);
4242

43+
#define list_for_each_entry_rcu_locked(pos, head, member) \
44+
list_for_each_entry_rcu(pos, head, member, \
45+
device_links_read_lock_held())
46+
4347
/*
4448
* The entries in the dpm_list list are in a depth first order, simply
4549
* because children are guaranteed to be discovered after parents, and
@@ -266,7 +270,7 @@ static void dpm_wait_for_suppliers(struct device *dev, bool async)
266270
* callbacks freeing the link objects for the links in the list we're
267271
* walking.
268272
*/
269-
list_for_each_entry_rcu(link, &dev->links.suppliers, c_node)
273+
list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node)
270274
if (READ_ONCE(link->status) != DL_STATE_DORMANT)
271275
dpm_wait(link->supplier, async);
272276

@@ -323,7 +327,7 @@ static void dpm_wait_for_consumers(struct device *dev, bool async)
323327
* continue instead of trying to continue in parallel with its
324328
* unregistration).
325329
*/
326-
list_for_each_entry_rcu(link, &dev->links.consumers, s_node)
330+
list_for_each_entry_rcu_locked(link, &dev->links.consumers, s_node)
327331
if (READ_ONCE(link->status) != DL_STATE_DORMANT)
328332
dpm_wait(link->consumer, async);
329333

@@ -1235,7 +1239,7 @@ static void dpm_superior_set_must_resume(struct device *dev)
12351239

12361240
idx = device_links_read_lock();
12371241

1238-
list_for_each_entry_rcu(link, &dev->links.suppliers, c_node)
1242+
list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node)
12391243
link->supplier->power.must_resume = true;
12401244

12411245
device_links_read_unlock(idx);
@@ -1695,7 +1699,7 @@ static void dpm_clear_superiors_direct_complete(struct device *dev)
16951699

16961700
idx = device_links_read_lock();
16971701

1698-
list_for_each_entry_rcu(link, &dev->links.suppliers, c_node) {
1702+
list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node) {
16991703
spin_lock_irq(&link->supplier->power.lock);
17001704
link->supplier->power.direct_complete = false;
17011705
spin_unlock_irq(&link->supplier->power.lock);

0 commit comments

Comments
 (0)