[PATCH 6/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices

Ulf Hansson ulf.hansson at linaro.org
Thu Jun 22 02:35:35 PDT 2017


On 21 June 2017 at 23:42, Rafael J. Wysocki <rafael at kernel.org> wrote:
> On Wed, Jun 21, 2017 at 9:21 PM, Ulf Hansson <ulf.hansson at linaro.org> wrote:
>> In some cases a driver for an ACPI device needs to be able to prevent the
>> ACPI PM domain from using the direct_complete path during system sleep.
>>
>> One typical case is when the driver for the device needs its device to stay
>> runtime enabled, during the __device_suspend phase. This isn't the case
>> when the direct_complete path is being executed by the PM core, as it then
>> disables runtime PM for the device in __device_suspend(). Any following
>> attempts to runtime resume the device after that point, just fails.
>>
>> A workaround to this problem is to let the driver runtime resume its device
>> from its ->prepare() callback, as that would prevent the direct_complete
>> path from being executed. However, that may often be a waste, especially if
>> it turned out that no one really needed the device.
>>
>> For this reason, invent acpi_dev_disable|enable_direct_complete(), to allow
>> drivers to inform the ACPI PM domain to change its default behaviour during
>> system sleep, and thus control whether it may use the direct_complete path
>> or not.
>>
>> Typically a driver should call acpi_dev_disable_direct_comlete() during
>> ->probe() and acpi_dev_enable_direct_complete() in ->remove().
>>
>> Signed-off-by: Ulf Hansson <ulf.hansson at linaro.org>
>> ---
>>  drivers/acpi/device_pm.c | 37 ++++++++++++++++++++++++++++++++++++-
>>  include/acpi/acpi_bus.h  |  1 +
>>  include/linux/acpi.h     |  4 ++++
>>  3 files changed, 41 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
>> index ee51e75..2393a1a 100644
>> --- a/drivers/acpi/device_pm.c
>> +++ b/drivers/acpi/device_pm.c
>> @@ -879,6 +879,41 @@ EXPORT_SYMBOL_GPL(acpi_subsys_runtime_resume);
>>
>>  #ifdef CONFIG_PM_SLEEP
>>  /**
>> + * acpi_dev_disable_direct_complete - Disable the direct_complete path for ACPI.
>> + * @dev: Device to disable the path for.
>> + *
>> + * Per default the ACPI PM domain tries to use the direct_complete path for its
>> + * devices during system sleep. This function allows a user, typically a driver
>> + * during probe, to disable the direct_complete path from being used by ACPI.
>> + */
>> +void acpi_dev_disable_direct_complete(struct device *dev)
>> +{
>> +       struct acpi_device *adev = ACPI_COMPANION(dev);
>> +
>> +       if (adev)
>> +               adev->no_direct_complete = true;
>
> We have an analogous flag in PCI now and it is called needs_resume, so
> it would be good to be consistent with that.

I was trying to come up with a nice name, however I couldn't find
anything better than no_direct_complete.

However as the next patch somewhat, extends the flag to also be use
for the runtime PM centric path, I should perhaps choose something
more related to that?

I think make "needs_resume" is going to e bit confusing, especially
while extending the usage for the flag it in the next patch, no?

>
>> +}
>> +EXPORT_SYMBOL_GPL(acpi_dev_disable_direct_complete);
>> +
>> +/**
>> + * acpi_dev_enable_direct_complete - Enable the direct_complete path for ACPI.
>> + * @dev: Device to enable the path for.
>> + *
>> + * Enable the direct_complete path to be used during system suspend for the ACPI
>> + * PM domain, which is the default option. Typically a driver that disabled the
>> + * path during ->probe(), must call this function during ->remove() to re-enable
>> + * the direct_complete path to be used by ACPI.
>> + */
>> +void acpi_dev_enable_direct_complete(struct device *dev)
>> +{
>> +       struct acpi_device *adev = ACPI_COMPANION(dev);
>> +
>> +       if (adev)
>> +               adev->no_direct_complete = false;
>> +}
>> +EXPORT_SYMBOL_GPL(acpi_dev_enable_direct_complete);
>> +
>> +/**
>>   * acpi_dev_suspend_late - Put device into a low-power state using ACPI.
>>   * @dev: Device to put into a low-power state.
>>   *
>> @@ -967,7 +1002,7 @@ int acpi_subsys_prepare(struct device *dev)
>>         if (ret < 0)
>>                 return ret;
>>
>> -       if (!adev || !pm_runtime_suspended(dev))
>> +       if (!adev || adev->no_direct_complete || !pm_runtime_suspended(dev))
>>                 return 0;
>>
>>         return !acpi_dev_needs_resume(dev, adev);
>> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
>> index 63a90a6..2293d24 100644
>> --- a/include/acpi/acpi_bus.h
>> +++ b/include/acpi/acpi_bus.h
>> @@ -380,6 +380,7 @@ struct acpi_device {
>>         struct list_head physical_node_list;
>>         struct mutex physical_node_lock;
>>         void (*remove)(struct acpi_device *);
>> +       bool no_direct_complete;
>
> Also what about adding this to struct acpi_device_power instead?

Yes, thanks for the suggestion!

>
> Thanks,
> Rafael

Kind regards
Uffe



More information about the linux-arm-kernel mailing list