Skip to content
  • Rafael J. Wysocki's avatar
    PM: Make system-wide PM and runtime PM treat subsystems consistently · 9659cc06
    Rafael J. Wysocki authored
    
    
    The code handling system-wide power transitions (eg. suspend-to-RAM)
    can in theory execute callbacks provided by the device's bus type,
    device type and class in each phase of the power transition.  In
    turn, the runtime PM core code only calls one of those callbacks at
    a time, preferring bus type callbacks to device type or class
    callbacks and device type callbacks to class callbacks.
    
    It seems reasonable to make them both behave in the same way in that
    respect.  Moreover, even though a device may belong to two subsystems
    (eg. bus type and device class) simultaneously, in practice power
    management callbacks for system-wide power transitions are always
    provided by only one of them (ie. if the bus type callbacks are
    defined, the device class ones are not and vice versa).  Thus it is
    possible to modify the code handling system-wide power transitions
    so that it follows the core runtime PM code (ie. treats the
    subsystem callbacks as mutually exclusive).
    
    On the other hand, the core runtime PM code will choose to execute,
    for example, a runtime suspend callback provided by the device type
    even if the bus type's struct dev_pm_ops object exists, but the
    runtime_suspend pointer in it happens to be NULL.  This is confusing,
    because it may lead to the execution of callbacks from different
    subsystems during different operations (eg. the bus type suspend
    callback may be executed during runtime suspend of the device, while
    the device type callback will be executed during system suspend).
    
    Make all of the power management code treat subsystem callbacks in
    a consistent way, such that:
    (1) If the device's type is defined (eg. dev->type is not NULL)
        and its pm pointer is not NULL, the callbacks from dev->type->pm
        will be used.
    (2) If dev->type is NULL or dev->type->pm is NULL, but the device's
        class is defined (eg. dev->class is not NULL) and its pm pointer
        is not NULL, the callbacks from dev->class->pm will be used.
    (3) If dev->type is NULL or dev->type->pm is NULL and dev->class is
        NULL or dev->class->pm is NULL, the callbacks from dev->bus->pm
        will be used provided that both dev->bus and dev->bus->pm are
        not NULL.
    
    Signed-off-by: default avatarRafael J. Wysocki <rjw@sisk.pl>
    Acked-by: default avatarKevin Hilman <khilman@ti.com>
    Reasoning-sounds-sane-to: Grant Likely <grant.likely@secretlab.ca>
    Acked-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
    9659cc06