• Kevin Hilman's avatar
    PM / Runtime: let rpm_resume() succeed if RPM_ACTIVE, even when disabled, v2 · 6f3c77b0
    Kevin Hilman authored
    There are several drivers where the return value of
    pm_runtime_get_sync() is used to decide whether or not it is safe to
    access hardware and that don't provide .suspend() callbacks for system
    suspend (but may use late/noirq callbacks.)  If such a driver happens
    to call pm_runtime_get_sync() during system suspend, after the core
    has disabled runtime PM, it will get the error code and will decide
    that the hardware should not be accessed, although this may be a wrong
    conclusion, depending on the state of the device when runtime PM was
    disabled.
    
    Drivers might work around this problem by using a test like:
    
       ret = pm_runtime_get_sync(dev);
       if (!ret || (ret == -EACCES && driver_private_data(dev)->suspended)) {
          /* access hardware */
       }
    
    where driver_private_data(dev)->suspended is a flag set by the
    driver's .suspend() method (that would have to be added for this
    purpose).  However, that potentially would need to be done by multiple
    drivers which means quite a lot of duplicated code and bloat.
    
    To avoid that we can use the observation that the core sets
    dev->power.is_suspended before disabling runtime PM and use that
    instead of the driver's private flag.  Still, potentially many drivers
    would need to repeat that same check in quite a few places, so it's
    better to let the core do it.
    
    Then we can be a bit smarter and check whether or not runtime PM was
    disabled by the core only (disable_depth == 1) or by someone else in
    addition to the core (disable_depth > 1).  In the former case
    rpm_resume() can return 1 if the runtime PM status is RPM_ACTIVE,
    because it means the device was active when the core disabled runtime
    PM.  In the latter case it should still return -EACCES, because it
    isn't clear why runtime PM has been disabled.
    
    Tested on AM3730/Beagle-xM where a wakeup IRQ firing during the late
    suspend phase triggers runtime PM activity in the I2C driver since the
    wakeup IRQ is on an I2C-connected PMIC.
    
    [rjw: Modified whitespace to follow the file's convention.]
    Signed-off-by: default avatarKevin Hilman <khilman@ti.com>
    Signed-off-by: default avatarRafael J. Wysocki <rjw@sisk.pl>
    6f3c77b0
runtime.c 35.9 KB