On Tue, Jan 21, 2020 at 2:41 PM Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx> wrote: > > Add a convenience function to tell whether a device is in low power state, > primarily for use in drivers' probe or remove functions on busses where > the custom is to power on the device for the duration of both. > > Returns false on non-ACPI systems. > > Suggested-by: Mika Westerberg <mika.westerberg@xxxxxxxxxxxxxxx> > Signed-off-by: Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx> Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx> > --- > drivers/acpi/device_pm.c | 31 +++++++++++++++++++++++++++++++ > include/linux/acpi.h | 5 +++++ > 2 files changed, 36 insertions(+) > > diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c > index 5e4a8860a9c0c..d3174c6edf915 100644 > --- a/drivers/acpi/device_pm.c > +++ b/drivers/acpi/device_pm.c > @@ -1348,4 +1348,35 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on) > return 1; > } > EXPORT_SYMBOL_GPL(acpi_dev_pm_attach); > + > +/** > + * acpi_dev_state_low_power - Check the current ACPI power state of a device. > + * @dev: Physical device the ACPI power state of which to check > + * > + * On a system without ACPI, return false. On a system with ACPI, return true if > + * the current ACPI power state of the device is not D0, or false otherwise. > + * > + * Note that the power state of a device is not well-defined after it has been > + * passed to acpi_device_set_power() and before that function returns, so it is > + * not valid to ask for the ACPI power state of the device in that time frame. > + */ > +bool acpi_dev_state_low_power(struct device *dev) > +{ > + struct acpi_device *adev = ACPI_COMPANION(dev); > + int power_state; > + int ret; > + > + if (!adev) > + return false; > + > + ret = acpi_device_get_power(adev, &power_state); > + if (ret) { > + dev_dbg(dev, "Cannot obtain power state (%d)\n", ret); > + return false; > + } > + > + return power_state != ACPI_STATE_D0; > +} > +EXPORT_SYMBOL_GPL(acpi_dev_state_low_power); > + > #endif /* CONFIG_PM */ > diff --git a/include/linux/acpi.h b/include/linux/acpi.h > index 0f37a7d5fa774..aa666da311444 100644 > --- a/include/linux/acpi.h > +++ b/include/linux/acpi.h > @@ -926,6 +926,7 @@ int acpi_dev_resume(struct device *dev); > int acpi_subsys_runtime_suspend(struct device *dev); > int acpi_subsys_runtime_resume(struct device *dev); > int acpi_dev_pm_attach(struct device *dev, bool power_on); > +bool acpi_dev_state_low_power(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; } > @@ -935,6 +936,10 @@ static inline int acpi_dev_pm_attach(struct device *dev, bool power_on) > { > return 0; > } > +static inline bool acpi_dev_state_low_power(struct device *dev) > +{ > + return false; > +} > #endif > > #if defined(CONFIG_ACPI) && defined(CONFIG_PM_SLEEP) > -- > 2.20.1 >