Hi Rafael, On Tue, Jun 22, 2021 at 03:40:05PM +0200, Rafael J. Wysocki wrote: > On Tue, Jun 22, 2021 at 12:20 AM Dmitry Torokhov > <dmitry.torokhov@xxxxxxxxx> wrote: > > > > Currently ACPI power domain brings devices into D0 state in the "resume > > early" phase. Normally this does not cause any issues, as powering up > > happens quickly. However there are peripherals that have certain timing > > requirements for powering on, for example some models of Elan > > touchscreens need 300msec after powering up/releasing reset line before > > they can accept commands from the host. Such devices will dominate > > the time spent in early resume phase and cause increase in overall > > resume time as we wait for early resume to complete before we can > > proceed to the normal resume stage. > > > > There are ways for a driver to indicate that it can tolerate device > > being in the low power mode and that it knows how to power the device > > back up when resuming, bit that requires changes to individual drivers > > that may not really care about details of ACPI controlled power > > management. > > > > This change attempts to solve this issue at ACPI power domain level, by > > postponing powering up device until we get to the normal resume stage, > > unless there is early resume handler defined for the device, or device > > does not declare any resume handlers, in which case we continue powering > > up such devices early. This allows us to shave off several hundred > > milliseconds of resume time on affected systems. > > > > Signed-off-by: Dmitry Torokhov <dmitry.torokhov@xxxxxxxxx> > > --- > > drivers/acpi/device_pm.c | 46 +++++++++++++++++++++++++++++++++++----- > > 1 file changed, 41 insertions(+), 5 deletions(-) > > > > diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c > > index 096153761ebc..00b412ccb2e0 100644 > > --- a/drivers/acpi/device_pm.c > > +++ b/drivers/acpi/device_pm.c > > @@ -1131,17 +1131,52 @@ static int acpi_subsys_resume_noirq(struct device *dev) > > * > > * Use ACPI to put the given device into the full-power state and carry out the > > * generic early resume procedure for it during system transition into the > > - * working state. > > + * working state, but only do that if device either defines early resume > > + * handler, or does not define power operations at all. Otherwise powering up > > + * of the device is postponed to the normal resume phase. > > */ > > static int acpi_subsys_resume_early(struct device *dev) > > { > > + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; > > + struct acpi_device *adev = ACPI_COMPANION(dev); > > int ret; > > > > - if (dev_pm_skip_resume(dev)) > > - return 0; > > The above doesn't need to be changed AFAICS. I was trying to have if string if/else if/else, but I can keep it as it was. > > > + if (dev_pm_skip_resume(dev)) { > > + ret = 0; > > + } else if (!pm || pm->resume_early) { > > This is rather tricky, but I don't see a particular reason why it wouldn't work. > > > + ret = acpi_dev_resume(dev); > > + if (!ret) > > + ret = pm_generic_resume_early(dev); > > + } else { > > + if (adev) > > + acpi_device_wakeup_disable(adev); > > This isn't necessary here. Just to confirm - you are saying that disabling the device as a wakeup source can be safely postponed till the normal resume stage? I was trying to keep as much of the original behavior as possible and this is a part of acpi_dev_resume() that we are now postponing. Thanks. -- Dmitry