Merge tag 'pm-5.7-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull more power management updates from Rafael Wysocki:
 "Additional power management updates.

  These fix a corner-case suspend-to-idle wakeup issue on systems where
  the ACPI SCI is shared with another wakeup source, add a kernel
  command line option to set pm_debug_messages via the kernel command
  line, add a document desctibing system-wide suspend and resume code
  flows, modify cpufreq Kconfig to choose schedutil as the preferred
  governor by default in a couple of cases and do some assorted
  cleanups.

  Specifics:

   - Fix corner-case suspend-to-idle wakeup issue on systems where the
     ACPI SCI is shared with another wakeup source (Hans de Goede).

   - Add document describing system-wide suspend and resume code flows
     to the admin guide (Rafael Wysocki).

   - Add kernel command line option to set pm_debug_messages (Chen Yu).

   - Choose schedutil as the preferred scaling governor by default on
     ARM big.LITTLE systems and on x86 systems using the intel_pstate
     driver in the passive mode (Linus Walleij, Rafael Wysocki).

   - Drop racy and redundant checks from the PM core's device_prepare()
     routine (Rafael Wysocki).

   - Make resume from hibernation take the hibernation_restore() return
     value into account (Dexuan Cui)"

* tag 'pm-5.7-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  platform/x86: intel_int0002_vgpio: Use acpi_register_wakeup_handler()
  ACPI: PM: Add acpi_[un]register_wakeup_handler()
  Documentation: PM: sleep: Document system-wide suspend code flows
  cpufreq: Select schedutil when using big.LITTLE
  PM: sleep: Add pm_debug_messages kernel command line option
  PM: sleep: core: Drop racy and redundant checks from device_prepare()
  PM: hibernate: Propagate the return value of hibernation_restore()
  cpufreq: intel_pstate: Select schedutil as the default governor
This commit is contained in:
Linus Torvalds
2020-04-06 10:14:39 -07:00
13개의 변경된 파일389개의 추가작업 그리고 8개의 파일을 삭제

파일 보기

@@ -1009,6 +1009,10 @@ static bool acpi_s2idle_wake(void)
if (acpi_any_fixed_event_status_set())
return true;
/* Check wakeups from drivers sharing the SCI. */
if (acpi_check_wakeup_handlers())
return true;
/*
* If the status bit is set for any enabled GPE other than the
* EC one, the wakeup is regarded as a genuine one.

파일 보기

@@ -2,6 +2,7 @@
extern void acpi_enable_wakeup_devices(u8 sleep_state);
extern void acpi_disable_wakeup_devices(u8 sleep_state);
extern bool acpi_check_wakeup_handlers(void);
extern struct list_head acpi_wakeup_device_list;
extern struct mutex acpi_device_lock;

파일 보기

@@ -12,6 +12,15 @@
#include "internal.h"
#include "sleep.h"
struct acpi_wakeup_handler {
struct list_head list_node;
bool (*wakeup)(void *context);
void *context;
};
static LIST_HEAD(acpi_wakeup_handler_head);
static DEFINE_MUTEX(acpi_wakeup_handler_mutex);
/*
* We didn't lock acpi_device_lock in the file, because it invokes oops in
* suspend/resume and isn't really required as this is called in S-state. At
@@ -90,3 +99,75 @@ int __init acpi_wakeup_device_init(void)
mutex_unlock(&acpi_device_lock);
return 0;
}
/**
* acpi_register_wakeup_handler - Register wakeup handler
* @wake_irq: The IRQ through which the device may receive wakeups
* @wakeup: Wakeup-handler to call when the SCI has triggered a wakeup
* @context: Context to pass to the handler when calling it
*
* Drivers which may share an IRQ with the SCI can use this to register
* a handler which returns true when the device they are managing wants
* to trigger a wakeup.
*/
int acpi_register_wakeup_handler(int wake_irq, bool (*wakeup)(void *context),
void *context)
{
struct acpi_wakeup_handler *handler;
/*
* If the device is not sharing its IRQ with the SCI, there is no
* need to register the handler.
*/
if (!acpi_sci_irq_valid() || wake_irq != acpi_sci_irq)
return 0;
handler = kmalloc(sizeof(*handler), GFP_KERNEL);
if (!handler)
return -ENOMEM;
handler->wakeup = wakeup;
handler->context = context;
mutex_lock(&acpi_wakeup_handler_mutex);
list_add(&handler->list_node, &acpi_wakeup_handler_head);
mutex_unlock(&acpi_wakeup_handler_mutex);
return 0;
}
EXPORT_SYMBOL_GPL(acpi_register_wakeup_handler);
/**
* acpi_unregister_wakeup_handler - Unregister wakeup handler
* @wakeup: Wakeup-handler passed to acpi_register_wakeup_handler()
* @context: Context passed to acpi_register_wakeup_handler()
*/
void acpi_unregister_wakeup_handler(bool (*wakeup)(void *context),
void *context)
{
struct acpi_wakeup_handler *handler;
mutex_lock(&acpi_wakeup_handler_mutex);
list_for_each_entry(handler, &acpi_wakeup_handler_head, list_node) {
if (handler->wakeup == wakeup && handler->context == context) {
list_del(&handler->list_node);
kfree(handler);
break;
}
}
mutex_unlock(&acpi_wakeup_handler_mutex);
}
EXPORT_SYMBOL_GPL(acpi_unregister_wakeup_handler);
bool acpi_check_wakeup_handlers(void)
{
struct acpi_wakeup_handler *handler;
/* No need to lock, nothing else is running when we're called. */
list_for_each_entry(handler, &acpi_wakeup_handler_head, list_node) {
if (handler->wakeup(handler->context))
return true;
}
return false;
}