1. 28 7月, 2015 1 次提交
    • M
      ACPI / PM: Use target_state to set the device power state · 71b65445
      Mika Westerberg 提交于
      Commit 20dacb71 ("ACPI / PM: Rework device power management to follow
      ACPI 6") changed the device power management to use D3hot if the device
      in question does not have _PR3 method even if D3cold was requested by the
      caller.
      
      However, if the device has _PR3 device->power.state is also set to D3hot
      instead of D3Cold after power resources have been turned off because
      device->power.state will be assigned from "state" instead of
      "target_state".
      
      Next time the device is transitioned to D0, acpi_power_transition() will
      find that the current power state of the device is D3hot instead of D3cold
      which causes it to power down all resources required for the current
      (wrong) state D3hot.
      
      Below is a simplified ASL example of a real touch panel device which
      triggers the problem:
      
        Scope (TPL1)
        {
            Name (_PR0, Package (1) { \_SB.PCI0.I2C1.PXTC })
            Name (_PR3, Package (1) { \_SB.PCI0.I2C1.PXTC })
            ...
        }
      
      In both D0 and D3hot the same power resource is required. However, when
      acpi_power_transition() turns off power resources required for D3hot (as
      the device is transitioned to D0) it powers down PXTC which then makes the
      device to lose its power.
      
      Fix this by assigning "target_state" to the device power state instead of
      "state" that is always D3hot even for devices with valid _PR3.
      
      Fixes: 20dacb71 (ACPI / PM: Rework device power management to follow ACPI 6)
      Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      71b65445
  2. 10 6月, 2015 1 次提交
  3. 16 5月, 2015 1 次提交
    • R
      ACPI / PM: Rework device power management to follow ACPI 6 · 20dacb71
      Rafael J. Wysocki 提交于
      The ACPI 6 specification has made some changes in the device power
      management area.  In particular:
      
       * The D3hot power state is now supposed to be always available
         (instead of D3cold) and D3cold is only regarded as valid if the
         _PR3 object is present for the given device.
      
       * The required ordering of transitions into power states deeper than
         D0 is now such that for a transition into state Dx the _PSx method
         is supposed to be executed first, if present, and the states of
         the power resources the device depends on are supposed to be
         changed after that.
      
       * It is now explicitly forbidden to transition devices from
         lower-power (deeper) into higher-power (shallower) power states
         other than D0.
      
      Those changes have been made so the specification reflects the
      Windows' device power management code that the vast majority of
      systems using ACPI is validated against.
      
      To avoid artificial differences in ACPI device power management
      between Windows and Linux, modify the ACPI device power management
      code to follow the new specification.  Add comments explaining the
      code flow in some unclear places.
      
      This only may affect some real corner cases in which the OS behavior
      expected by the firmware is different from the Windows one, but that's
      quite unlikely.  The transition ordering change affects transitions
      to D1 and D2 which are rarely used (if at all) and into D3hot and
      D3cold for devices actually having _PR3, but those are likely to
      be validated against Windows anyway.  The other changes may affect
      code calling acpi_device_get_power() or acpi_device_update_power()
      where ACPI_STATE_D3_HOT may be returned instead of ACPI_STATE_D3_COLD
      (that's why the ACPI fan driver needs to be updated too) and since
      transitions into ACPI_STATE_D3_HOT may remove power now, it is better
      to avoid this one in acpi_pm_device_sleep_state() if the "no power
      off" PM QoS flag is set.
      
      The only existing user of acpi_device_can_poweroff() really cares
      about the case when _PR3 is present, so the change in that function
      should not cause any problems to happen too.
      
      A plus is that PCI_D3hot can be mapped to ACPI_STATE_D3_HOT
      now and the compatibility with older systems should be covered
      automatically.
      
      In any case, if any real problems result from this, it still will
      be better to follow the Windows' behavior (which now is reflected
      by the specification too) in general and handle the cases when it
      doesn't work via quirks.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      20dacb71
  4. 09 2月, 2015 1 次提交
    • A
      ACPI / PM: Remove unneeded nested #ifdef · 8dcb52cb
      Andreas Ruprecht 提交于
      In commit 5de21bb9 ("ACPI / PM: Drop CONFIG_PM_RUNTIME from the
      ACPI core"), all occurrences of CONFIG_PM_RUNTIME were replaced with
      CONFIG_PM. This created the following structure of #ifdef blocks in
      the code:
      
       [...]
       #ifdef CONFIG_PM
       #ifdef CONFIG_PM
       /* always on / undead */
       #ifdef CONFIG_PM_SLEEP
       [...]
       #endif
       #endif
       [...]
       #endif
      
      This patch removes the inner "#ifdef CONFIG_PM" block as it will
      always be enabled when the outer block is enabled. This inconsistency
      was found using the undertaker-checkpatch tool.
      Signed-off-by: NAndreas Ruprecht <rupran@einserver.de>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      8dcb52cb
  5. 06 1月, 2015 1 次提交
    • R
      ACPI / PM: Fix PM initialization for devices that are not present · 1b1f3e16
      Rafael J. Wysocki 提交于
      If an ACPI device object whose _STA returns 0 (not present and not
      functional) has _PR0 or _PS0, its power_manageable flag will be set
      and acpi_bus_init_power() will return 0 for it.  Consequently, if
      such a device object is passed to the ACPI device PM functions, they
      will attempt to carry out the requested operation on the device,
      although they should not do that for devices that are not present.
      
      To fix that problem make acpi_bus_init_power() return an error code
      for devices that are not present which will cause power_manageable to
      be cleared for them as appropriate in acpi_bus_get_power_flags().
      However, the lists of power resources should not be freed for the
      device in that case, so modify acpi_bus_get_power_flags() to keep
      those lists even if acpi_bus_init_power() returns an error.
      Accordingly, when deciding whether or not the lists of power
      resources need to be freed, acpi_free_power_resources_lists()
      should check the power.flags.power_resources flag instead of
      flags.power_manageable, so make that change too.
      
      Furthermore, if acpi_bus_attach() sees that flags.initialized is
      unset for the given device, it should reset the power management
      settings of the device and re-initialize them from scratch instead
      of relying on the previous settings (the device may have appeared
      after being not present previously, for example), so make it use
      the 'valid' flag of the D0 power state as the initial value of
      flags.power_manageable for it and call acpi_bus_init_power() to
      discover its current power state.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Reviewed-by: NMika Westerberg <mika.westerberg@linux.intel.com>
      Cc: 3.10+ <stable@vger.kernel.org> # 3.10+
      1b1f3e16
  6. 13 12月, 2014 1 次提交
  7. 04 12月, 2014 1 次提交
  8. 25 11月, 2014 1 次提交
  9. 20 11月, 2014 1 次提交
    • R
      ACPI / PM: Ignore wakeup setting if the ACPI companion can't wake up · 78579b7c
      Rafael J. Wysocki 提交于
      As reported by Dmitry, on some Chromebooks there are devices with
      corresponding ACPI objects and with unusual system wakeup
      configuration.  Namely, they technically are wakeup-capable, but the
      wakeup is handled via a platform-specific out-of-band mechanism and
      the ACPI PM layer has no information on the wakeup capability.  As
      a result, device_may_wakeup(dev) called from acpi_dev_suspend_late()
      returns 'true' for those devices, but the wakeup.flags.valid flag is
      unset for the corresponding ACPI device objects, so acpi_device_wakeup()
      reproducibly fails for them causing acpi_dev_suspend_late() to return
      an error code.  The entire system suspend is then aborted and the
      machines in question cannot suspend at all.
      
      Address the problem by ignoring the device_may_wakeup(dev) return
      value in acpi_dev_suspend_late() if the ACPI companion of the device
      being handled has wakeup.flags.valid unset (in which case it is clear
      that the wakeup is supposed to be handled by other means).
      
      This fixes a regression introduced by commit a76e9bd8 (i2c:
      attach/detach I2C client device to the ACPI power domain) as the
      affected systems could suspend and resume successfully before that
      commit.
      
      Fixes: a76e9bd8 (i2c: attach/detach I2C client device to the ACPI power domain)
      Reported-by: NDmitry Torokhov <dtor@chromium.org>
      Reviewed-by: NDmitry Torokhov <dtor@chromium.org>
      Cc: 3.13+ <stable@vger.kernel.org> # 3.13+
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      78579b7c
  10. 24 10月, 2014 1 次提交
  11. 10 10月, 2014 1 次提交
  12. 22 9月, 2014 2 次提交
  13. 23 7月, 2014 3 次提交
    • R
      ACPI / PM: Use ACPI_COMPANION() instead of ACPI_HANDLE() · 17653a3e
      Rafael J. Wysocki 提交于
      The ACPI_HANDLE() macro evaluates ACPI_COMPANION() internally to
      return the handle of the device's ACPI companion, so it is much
      more straightforward and efficient to use ACPI_COMPANION()
      directly to obtain the device's ACPI companion object instead of
      using ACPI_HANDLE() and acpi_bus_get_device() on the returned
      handle for the same thing.
      
      Do that in three places in the ACPI device PM code.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      17653a3e
    • R
      ACPI / PM: Always enable wakeup GPEs when enabling device wakeup · f35cec25
      Rafael J. Wysocki 提交于
      Wakeup GPEs are currently only enabled when setting up devices for
      remote wakeup at run time.  During system-wide transitions they are
      enabled by ACPICA at the very last stage of suspend (before asking
      the BIOS to take over).  Of course, that only works for system
      sleep states supported by ACPI, so in particular it doesn't work
      for the "freeze" sleep state.
      
      For this reason, modify the ACPI core device PM code to enable wakeup
      GPEs for devices when setting them up for wakeup regardless of whether
      that is remote wakeup at runtime or system wakeup.  That allows the
      same device wakeup setup routine to be used for both runtime PM and
      system-wide PM and makes it possible to reduce code size quite a bit.
      
      This make ACPI-based PCI Wake-on-LAN work with the "freeze" sleep
      state on my venerable Toshiba Portege R500 and should help other
      systems too.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      f35cec25
    • R
      ACPI / PM: Revork the handling of ACPI device wakeup notifications · c072530f
      Rafael J. Wysocki 提交于
      Since ACPI wakeup GPEs are going to be enabled during system suspend
      as well as for runtime wakeup by a subsequent patch and the same
      notify handlers will be used in both cases, rework the ACPI device
      wakeup notification framework so that the part specific to physical
      devices is always run asynchronously from the PM workqueue.  This
      prevents runtime resume callbacks for those devices from being
      run during system suspend and resume which may not be appropriate,
      among other things.
      
      Also make ACPI device wakeup notification handling a bit more robust
      agaist subsequent removal of ACPI device objects, whould that ever
      happen, and create a wakeup source object for each ACPI device
      configured for wakeup so that wakeup notifications for those
      devices can wake up the system from the "freeze" sleep state.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      c072530f
  14. 20 5月, 2014 2 次提交
  15. 04 3月, 2014 1 次提交
    • R
      ACPI / PM: Resume runtime-suspended devices later during system suspend · 92858c47
      Rafael J. Wysocki 提交于
      Runtime-suspended devices are resumed during system suspend by
      acpi_subsys_prepare() for two reasons: First, because they may need
      to be reprogrammed in order to change their wakeup settings and,
      second, because they may need to be operatonal for their children
      to be successfully suspended.  That is a problem, though, if there
      are many runtime-suspended devices that need to be resumed this
      way during system suspend, because the .prepare() PM callbacks of
      devices are executed sequentially and the times taken by them
      accumulate, which may increase the total system suspend time quite
      a bit.
      
      For this reason, move the resume of runtime-suspended devices up
      to the next phase of device suspend (during system suspend), except
      for the ones that have power.ignore_children set.  The exception is
      made, because the devices with power.ignore_children set may still
      be necessary for their children to be successfully suspended (during
      system suspend) and they won't be resumed automatically as a result
      of the runtime resume of their children.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      92858c47
  16. 28 1月, 2014 1 次提交
  17. 23 11月, 2013 1 次提交
    • R
      ACPI / scan: Add acpi_device objects for all device nodes in the namespace · 202317a5
      Rafael J. Wysocki 提交于
      Modify the ACPI namespace scanning code to register a struct
      acpi_device object for every namespace node representing a device,
      processor and so on, even if the device represented by that namespace
      node is reported to be not present and not functional by _STA.
      
      There are multiple reasons to do that.  First of all, it avoids
      quite a lot of overhead when struct acpi_device objects are
      deleted every time acpi_bus_trim() is run and then added again
      by a subsequent acpi_bus_scan() for the same scope, although the
      namespace objects they correspond to stay in memory all the time
      (which always is the case on a vast majority of systems).
      
      Second, it will allow user space to see that there are namespace
      nodes representing devices that are not present at the moment and may
      be added to the system.  It will also allow user space to evaluate
      _SUN for those nodes to check what physical slots the "missing"
      devices may be put into and it will make sense to add a sysfs
      attribute for _STA evaluation after this change (that will be
      useful for thermal management on some systems).
      
      Next, it will help to consolidate the ACPI hotplug handling among
      subsystems by making it possible to store hotplug-related information
      in struct acpi_device objects in a standard common way.
      
      Finally, it will help to avoid a race condition related to the
      deletion of ACPI namespace nodes.  Namely, namespace nodes may be
      deleted as a result of a table unload triggered by _EJ0 or _DCK.
      If a hotplug notification for one of those nodes is triggered
      right before the deletion and it executes a hotplug callback
      via acpi_hotplug_execute(), the ACPI handle passed to that
      callback may be stale when the callback actually runs.  One way
      to work around that is to always pass struct acpi_device pointers
      to hotplug callbacks after doing a get_device() on the objects in
      question which eliminates the use-after-free possibility (the ACPI
      handles in those objects are invalidated by acpi_scan_drop_device(),
      so they will trigger ACPICA errors on attempts to use them).
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Tested-by: NMika Westerberg <mika.westerberg@linux.intel.com>
      202317a5
  18. 15 11月, 2013 2 次提交
    • R
      ACPI: Eliminate the DEVICE_ACPI_HANDLE() macro · 3a83f992
      Rafael J. Wysocki 提交于
      Since DEVICE_ACPI_HANDLE() is now literally identical to
      ACPI_HANDLE(), replace it with the latter everywhere and drop its
      definition from include/acpi.h.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Acked-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      3a83f992
    • R
      ACPI / driver core: Store an ACPI device pointer in struct acpi_dev_node · 7b199811
      Rafael J. Wysocki 提交于
      Modify struct acpi_dev_node to contain a pointer to struct acpi_device
      associated with the given device object (that is, its ACPI companion
      device) instead of an ACPI handle corresponding to it.  Introduce two
      new macros for manipulating that pointer in a CONFIG_ACPI-safe way,
      ACPI_COMPANION() and ACPI_COMPANION_SET(), and rework the
      ACPI_HANDLE() macro to take the above changes into account.
      Drop the ACPI_HANDLE_SET() macro entirely and rework its users to
      use ACPI_COMPANION_SET() instead.  For some of them who used to
      pass the result of acpi_get_child() directly to ACPI_HANDLE_SET()
      introduce a helper routine acpi_preset_companion() doing an
      equivalent thing.
      
      The main motivation for doing this is that there are things
      represented by struct acpi_device objects that don't have valid
      ACPI handles (so called fixed ACPI hardware features, such as
      power and sleep buttons) and we would like to create platform
      device objects for them and "glue" them to their ACPI companions
      in the usual way (which currently is impossible due to the
      lack of valid ACPI handles).  However, there are more reasons
      why it may be useful.
      
      First, struct acpi_device pointers allow of much better type checking
      than void pointers which are ACPI handles, so it should be more
      difficult to write buggy code using modified struct acpi_dev_node
      and the new macros.  Second, the change should help to reduce (over
      time) the number of places in which the result of ACPI_HANDLE() is
      passed to acpi_bus_get_device() in order to obtain a pointer to the
      struct acpi_device associated with the given "physical" device,
      because now that pointer is returned by ACPI_COMPANION() directly.
      Finally, the change should make it easier to write generic code that
      will build both for CONFIG_ACPI set and unset without adding explicit
      compiler directives to it.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Acked-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com> # on Haswell
      Reviewed-by: NMika Westerberg <mika.westerberg@linux.intel.com>
      Reviewed-by: Aaron Lu <aaron.lu@intel.com> # for ATA and SDIO part
      7b199811
  19. 17 10月, 2013 1 次提交
  20. 11 10月, 2013 1 次提交
    • M
      ACPI / PM: allow child devices to ignore parent power state · 644f17ad
      Mika Westerberg 提交于
      Some serial buses like I2C and SPI don't require that the parent device is
      in D0 before any of its children transitions to D0, but instead the parent
      device can control its own power independently from the children.
      
      This does not follow the ACPI specification as it requires the parent to be
      powered on before its children. However, Windows seems to ignore this
      requirement so I think we can do the same in Linux.
      
      Implement this by adding a new power flag 'ignore_parent' to struct
      acpi_device.  If this flag is set the ACPI core ignores checking of the
      parent device power state when the device is powered on/off.
      Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      644f17ad
  21. 04 8月, 2013 1 次提交
  22. 31 7月, 2013 1 次提交
  23. 30 7月, 2013 2 次提交
  24. 04 7月, 2013 1 次提交
    • R
      ACPI / PM: Fix corner case in acpi_bus_update_power() · 91bdad0b
      Rafael J. Wysocki 提交于
      The role of acpi_bus_update_power() is to update the given ACPI
      device object's power.state field to reflect the current physical
      state of the device (as inferred from the configuration of power
      resources and _PSC, if available).  For this purpose it calls
      acpi_device_set_power() that should update the power resources'
      reference counters and set power.state as appropriate.  However,
      that doesn't work if the "new" state is D1, D2 or D3hot and the
      the current value of power.state means D3cold, because in that
      case acpi_device_set_power() will refuse to transition the device
      from D3cold to non-D0.
      
      To address this problem, make acpi_bus_update_power() call
      acpi_power_transition() directly to update the power resources'
      reference counters and only use acpi_device_set_power() to put
      the device into D0 if the current physical state of it cannot
      be determined.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Cc: 3.9+ <stable@vger.kernel.org>
      91bdad0b
  25. 28 6月, 2013 1 次提交
  26. 20 6月, 2013 4 次提交
    • R
      ACPI / LPSS: Power up LPSS devices during enumeration · b9e95fc6
      Rafael J. Wysocki 提交于
      Commit 7cd8407d (ACPI / PM: Do not execute _PS0 for devices without
      _PSC during initialization) introduced a regression on some systems
      with Intel Lynxpoint Low-Power Subsystem (LPSS) where some devices
      need to be powered up during initialization, but their device objects
      in the ACPI namespace have _PS0 and _PS3 only (without _PSC or power
      resources).
      
      To work around this problem, make the ACPI LPSS driver power up
      devices it knows about by using a new helper function
      acpi_device_fix_up_power() that does all of the necessary
      sanity checks and calls acpi_dev_pm_explicit_set() to put the
      device into D0.
      Reported-and-tested-by: NMika Westerberg <mika.westerberg@linux.intel.com>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      b9e95fc6
    • R
      ACPI / PM: Rework and clean up acpi_dev_pm_get_state() · fa1675b5
      Rafael J. Wysocki 提交于
      The acpi_dev_pm_get_state() function defined in device_pm.c is quite
      convoluted, which isn't really necessary, and it doesn't validate the
      values returned by the ACPI methods executed by it appropriately.
      
      To address these shortcomings modify it in the following way.
      
       (1) Make its return value only mean whether or not it succeeded and
           pass the device power states determined by it through pointers.
      
       (2) Drop the d_max_in argument, used by only one of its callers,
           from it, and move the code related to d_max_in into that caller,
           acpi_pm_device_sleep_state().
      
       (3) Make it always check the return value of acpi_evaluate_integer()
           and handle failures as appropriate.  Moreover, make it check if
           the values returned by the executed ACPI methods are not out of
           range.
      
       (4) Make it check if the values returned by the executed ACPI
           methods represent valid power states of the given device and
           handle situations in which that's not the case gracefully.
      
      Also update the kerneldoc comments of acpi_dev_pm_get_state() and
      acpi_pm_device_sleep_state() to reflect the code changes.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      fa1675b5
    • R
      ACPI / PM: Replace ACPI_STATE_D3 with ACPI_STATE_D3_COLD in device_pm.c · 4c164ae7
      Rafael J. Wysocki 提交于
      The two symbols ACPI_STATE_D3 and ACPI_STATE_D3_COLD actually
      represent the same number (4), but ACPI_STATE_D3 is slightly
      ambigugous, because it may not be clear that it really means D3cold
      and not D3hot at first sight.
      
      Remove that ambiguity from drivers/acpi/device_pm.c by making it
      use ACPI_STATE_D3_COLD everywhere instead of ACPI_STATE_D3.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      4c164ae7
    • R
      ACPI / PM: Rename function acpi_device_power_state() and make it static · b25c77ef
      Rafael J. Wysocki 提交于
      There is a name clash between function acpi_device_power_state()
      defined in drivers/acpi/device_pm.c and structure type
      acpi_device_power_state defined in include/acpi/acpi_bus.h, which
      may be resolved by renaming the function.  Additionally, that
      funtion may be made static, because it is not used anywhere outside
      of the file it is defined in.
      
      Rename acpi_device_power_state() to acpi_dev_pm_get_state(), which
      better reflects its purpose, and make it static.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      b25c77ef
  27. 07 6月, 2013 1 次提交
  28. 04 6月, 2013 1 次提交
  29. 22 5月, 2013 1 次提交
    • R
      ACPI / PM: Allow device power states to be used for CONFIG_PM unset · ec4602a9
      Rafael J. Wysocki 提交于
      Currently, drivers/acpi/device_pm.c depends on CONFIG_PM and all of
      the functions defined in there are replaced with static inline stubs
      if that option is unset.  However, CONFIG_PM means, roughly, "runtime
      PM or suspend/hibernation support" and some of those functions are
      useful regardless of that.  For example, they are used by the ACPI
      fan driver for controlling fans and acpi_device_set_power() is called
      during device removal.  Moreover, device initialization may depend on
      setting device power states properly.
      
      For these reasons, make the routines manipulating ACPI device power
      states defined in drivers/acpi/device_pm.c available for CONFIG_PM
      unset too.
      Reported-by: NZhang Rui <rui.zhang@intel.com>
      Reported-and-tested-by: NMichel Lespinasse <walken@google.com>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Cc: 3.9+ <stable@vger.kernel.org>
      ec4602a9
  30. 25 3月, 2013 1 次提交
    • R
      ACPI / PM: Fix potential problem in acpi_device_get_power() · 75eb2d13
      Rafael J. Wysocki 提交于
      Theoretically, in some situations acpi_device_get_power() may return
      an incorrect result, because the settings of the power resources
      depended on by the device may indicate a power state shallower than
      the actual power state of the device.
      
      Say that two devices, A and B, depend on two power resources, X and
      Y, in such a way that _PR0 for both A and B list both X and Y and
      _PR3 for both A and B list power resource Y alone.  Also suppose
      that _PS0 and _PS3 are present for both A and B.  Then, if devices
      A and B are initially in D0, power resources X and Y are initially
      "on" and their reference counters are equal to 2.  To put device A
      into power state D3hot the kernel will decrement the reference
      counter of power resource X, but that power resource won't be turned
      off, because it is still in use by device B (its reference counter is
      equal to 1).  Next, _PS3 will be executed for device A.  Afterward
      the configuration of the power resources will indicate that device
      A is in power state D0 (both X and Y are "on"), but in fact it is
      in D3hot (because _PS3 has been executed for it).
      
      In that situation, if acpi_device_get_power() is called to get the
      power state of device A, it will first execute _PSC for it which
      should return 3.  That will cause acpi_device_get_power() to run
      acpi_power_get_inferred_state() for device A and the resultant power
      state will be D0, which is incorrect.
      
      To fix that change acpi_device_get_power() to first execute
      acpi_power_get_inferred_state() for the given device (if it
      depends on power resources) and to evaluate _PSC for it subsequently,
      so that the result inferred from the power resources configuration
      can be amended by the _PSC return value.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Reviewed-by: NAaron Lu <aaron.lu@intel.com>
      75eb2d13
  31. 03 2月, 2013 1 次提交
    • R
      ACPI / PM: Handle missing _PSC in acpi_bus_update_power() · 511d5c42
      Rafael J. Wysocki 提交于
      If _PS0 is defined for an ACPI device node, but _PSC isn't and
      the device node doesn't use power resources for power management,
      acpi_bus_update_power() will fail to update the power state of it,
      because acpi_device_get_power() returns ACPI_STATE_UNKNOWN in that
      case.
      
      To handle that situation make acpi_bus_update_power() follow
      acpi_bus_init_power() and try to force the given device node into
      power state D0.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      511d5c42