From e5cc8ef31267317f3e177415c84e3f3602e5bfc9 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 2 Nov 2012 01:41:01 +0100 Subject: ACPI / PM: Provide ACPI PM callback routines for subsystems Some bus types don't support power management natively, but generally there may be device nodes in ACPI tables corresponding to the devices whose bus types they are (under ACPI 5 those bus types may be SPI, I2C and platform). If that is the case, standard ACPI power management may be applied to those devices, although currently the kernel has no means for that. For this reason, provide a set of routines that may be used as power management callbacks for such devices. This may be done in three different ways. (1) Device drivers handling the devices in question may run acpi_dev_pm_attach() in their .probe() routines, which (on success) will cause the devices to be added to the general ACPI PM domain and ACPI power management will be used for them going forward. Then, acpi_dev_pm_detach() may be used to remove the devices from the general ACPI PM domain if ACPI power management is not necessary for them any more. (2) The devices' subsystems may use acpi_subsys_runtime_suspend(), acpi_subsys_runtime_resume(), acpi_subsys_prepare(), acpi_subsys_suspend_late(), acpi_subsys_resume_early() as their power management callbacks in the same way as the general ACPI PM domain does that. (3) The devices' drivers may execute acpi_dev_suspend_late(), acpi_dev_resume_early(), acpi_dev_runtime_suspend(), acpi_dev_runtime_resume() from their power management callbacks as appropriate, if that's absolutely necessary, but it is not recommended to do that, because such drivers may not work without ACPI support as a result. Signed-off-by: Rafael J. Wysocki --- include/linux/acpi.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'include/linux/acpi.h') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 90be9898110..0676b6ac57f 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -430,4 +430,38 @@ acpi_status acpi_os_prepare_sleep(u8 sleep_state, #define acpi_os_set_prepare_sleep(func, pm1a_ctrl, pm1b_ctrl) do { } while (0) #endif +#if defined(CONFIG_ACPI) && defined(CONFIG_PM_RUNTIME) +int acpi_dev_runtime_suspend(struct device *dev); +int acpi_dev_runtime_resume(struct device *dev); +int acpi_subsys_runtime_suspend(struct device *dev); +int acpi_subsys_runtime_resume(struct device *dev); +#else +static inline int acpi_dev_runtime_suspend(struct device *dev) { return 0; } +static inline int acpi_dev_runtime_resume(struct device *dev) { return 0; } +static inline int acpi_subsys_runtime_suspend(struct device *dev) { return 0; } +static inline int acpi_subsys_runtime_resume(struct device *dev) { return 0; } +#endif + +#ifdef CONFIG_ACPI_SLEEP +int acpi_dev_suspend_late(struct device *dev); +int acpi_dev_resume_early(struct device *dev); +int acpi_subsys_prepare(struct device *dev); +int acpi_subsys_suspend_late(struct device *dev); +int acpi_subsys_resume_early(struct device *dev); +#else +static inline int acpi_dev_suspend_late(struct device *dev) { return 0; } +static inline int acpi_dev_resume_early(struct device *dev) { return 0; } +static inline int acpi_subsys_prepare(struct device *dev) { return 0; } +static inline int acpi_subsys_suspend_late(struct device *dev) { return 0; } +static inline int acpi_subsys_resume_early(struct device *dev) { return 0; } +#endif + +#if defined(CONFIG_ACPI) && defined(CONFIG_PM) +int acpi_dev_pm_attach(struct device *dev); +int acpi_dev_pm_detach(struct device *dev); +#else +static inline int acpi_dev_pm_attach(struct device *dev) { return -ENODEV; } +static inline void acpi_dev_pm_detach(struct device *dev) {} +#endif + #endif /*_LINUX_ACPI_H*/ -- cgit v1.2.3 From 5133375bb46a0d6c3fba07097caed7aa5e629ccd Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 15 Nov 2012 13:15:37 +0100 Subject: ACPI / PM: Fix build problem when CONFIG_ACPI or CONFIG_PM is not set Commit e5cc8ef (ACPI / PM: Provide ACPI PM callback routines for subsystems) introduced a build problem occuring if CONFIG_ACPI is unset or CONFIG_PM is unset and errno.h is not included before acpi.h, because in that case ENODEV used in acpi.h is undefined. Fix the issue by making acpi.h include errno.h. Signed-off-by: Rafael J. Wysocki --- include/linux/acpi.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux/acpi.h') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 0676b6ac57f..5fdd8727151 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -25,6 +25,7 @@ #ifndef _LINUX_ACPI_H #define _LINUX_ACPI_H +#include #include /* for struct resource */ #ifdef CONFIG_ACPI -- cgit v1.2.3 From b88ce2a41562d1a9554f209e0f31a32d9f473794 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 26 Nov 2012 10:03:06 +0100 Subject: ACPI / PM: Allow attach/detach routines to change device power states Make it possible to ask the routines used for adding/removing devices to/from the general ACPI PM domain, acpi_dev_pm_attach() and acpi_dev_pm_detach(), respectively, to change the power states of devices so that they are put into the full-power state automatically by acpi_dev_pm_attach() and into the lowest-power state available automatically by acpi_dev_pm_detach(). Signed-off-by: Rafael J. Wysocki Reviewed-by: Mika Westerberg Tested-by: Mika Westerberg --- include/linux/acpi.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'include/linux/acpi.h') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 5fdd8727151..28ba643c92c 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -458,11 +458,14 @@ static inline int acpi_subsys_resume_early(struct device *dev) { return 0; } #endif #if defined(CONFIG_ACPI) && defined(CONFIG_PM) -int acpi_dev_pm_attach(struct device *dev); -int acpi_dev_pm_detach(struct device *dev); +int acpi_dev_pm_attach(struct device *dev, bool power_on); +int acpi_dev_pm_detach(struct device *dev, bool power_off); #else -static inline int acpi_dev_pm_attach(struct device *dev) { return -ENODEV; } -static inline void acpi_dev_pm_detach(struct device *dev) {} +static inline int acpi_dev_pm_attach(struct device *dev, bool power_on) +{ + return -ENODEV; +} +static inline void acpi_dev_pm_detach(struct device *dev, bool power_off) {} #endif #endif /*_LINUX_ACPI_H*/ -- cgit v1.2.3