1. 22 5月, 2020 1 次提交
  2. 13 5月, 2020 3 次提交
  3. 15 4月, 2020 1 次提交
    • H
      i2c: designware: platdrv: Remove DPM_FLAG_SMART_SUSPEND flag on BYT and CHT · d79294d0
      Hans de Goede 提交于
      We already set DPM_FLAG_SMART_PREPARE, so we completely skip all
      callbacks (other then prepare) where possible, quoting from
      dw_i2c_plat_prepare():
      
              /*
               * If the ACPI companion device object is present for this device, it
               * may be accessed during suspend and resume of other devices via I2C
               * operation regions, so tell the PM core and middle layers to avoid
               * skipping system suspend/resume callbacks for it in that case.
               */
              return !has_acpi_companion(dev);
      
      Also setting the DPM_FLAG_SMART_SUSPEND will cause acpi_subsys_suspend()
      to leave the controller runtime-suspended even if dw_i2c_plat_prepare()
      returned 0.
      
      Leaving the controller runtime-suspended normally, when the I2C controller
      is suspended during the suspend_late phase, is not an issue because
      the pm_runtime_get_sync() done by i2c_dw_xfer() will (runtime-)resume it.
      
      But for dw I2C controllers on Bay- and Cherry-Trail devices acpi_lpss.c
      leaves the controller alive until the suspend_noirq phase, because it may
      be used by the _PS3 ACPI methods of PCI devices and PCI devices are left
      powered on until the suspend_noirq phase.
      
      Between the suspend_late and resume_early phases runtime-pm is disabled.
      So for any ACPI I2C OPRegion accesses done after the suspend_late phase,
      the pm_runtime_get_sync() done by i2c_dw_xfer() is a no-op and the
      controller is left runtime-suspended.
      
      i2c_dw_xfer() has a check to catch this condition (rather then waiting
      for the I2C transfer to timeout because the controller is suspended).
      acpi_subsys_suspend() leaving the controller runtime-suspended in
      combination with an ACPI I2C OPRegion access done after the suspend_late
      phase triggers this check, leading to the following error being logged
      on a Bay Trail based Lenovo Thinkpad 8 tablet:
      
      [   93.275882] i2c_designware 80860F41:00: Transfer while suspended
      [   93.275993] WARNING: CPU: 0 PID: 412 at drivers/i2c/busses/i2c-designware-master.c:429 i2c_dw_xfer+0x239/0x280
      ...
      [   93.276252] Workqueue: kacpi_notify acpi_os_execute_deferred
      [   93.276267] RIP: 0010:i2c_dw_xfer+0x239/0x280
      ...
      [   93.276340] Call Trace:
      [   93.276366]  __i2c_transfer+0x121/0x520
      [   93.276379]  i2c_transfer+0x4c/0x100
      [   93.276392]  i2c_acpi_space_handler+0x219/0x510
      [   93.276408]  ? up+0x40/0x60
      [   93.276419]  ? i2c_acpi_notify+0x130/0x130
      [   93.276433]  acpi_ev_address_space_dispatch+0x1e1/0x252
      ...
      
      So since on BYT and CHT platforms we want ACPI I2c OPRegion accesses
      to work until the suspend_noirq phase, we need the controller to be
      runtime-resumed during the suspend phase if it is runtime-suspended
      suspended at that time. This means that we must not set the
      DPM_FLAG_SMART_SUSPEND on these platforms.
      
      On BYT and CHT we already have a special ACCESS_NO_IRQ_SUSPEND flag
      to make sure the controller stays functional until the suspend_noirq
      phase. This commit makes the driver not set the DPM_FLAG_SMART_SUSPEND
      flag when that flag is set.
      
      Cc: stable@vger.kernel.org
      Fixes: b30f2f65 ("i2c: designware: Set IRQF_NO_SUSPEND flag for all BYT and CHT controllers")
      Signed-off-by: NHans de Goede <hdegoede@redhat.com>
      Reviewed-by: NAndy Shevchenko <andriy.shevchenko@linux.intel.com>
      Acked-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Acked-by: NJarkko Nikula <jarkko.nikula@linux.intel.com>
      Signed-off-by: NWolfram Sang <wsa@the-dreams.de>
      d79294d0
  4. 25 3月, 2020 1 次提交
  5. 22 3月, 2020 1 次提交
  6. 03 2月, 2020 1 次提交
  7. 30 8月, 2019 2 次提交
  8. 21 3月, 2019 1 次提交
  9. 14 3月, 2019 2 次提交
    • H
      i2c: i2c-designware-platdrv: Always use a dynamic adapter number · cd86d140
      Hans de Goede 提交于
      Before this commit the i2c-designware-platdrv assumes that if the pdev
      has an apci-companion it should use a dynamic adapter-nr and it sets
      adapter->nr to -1, otherwise it will use pdev->id as adapter->nr.
      
      There are 3 ways how platform_device-s to which i2c-designware-platdrv
      will bind can be instantiated:
      
      1) Through of / devicetree
      2) Through ACPI enumeration
      3) Explicitly instantiated through platform_device_create + add
      
      1) In case of devicetree-instantiation the drivers/of code always sets
      pdev->id to PLATFORM_DEVID_NONE, which is -1 so in this case both paths
      to set adapter->nr end up doing the same thing.
      
      2) In case of ACPI instantiation the device will always have an
      ACPI-companion, so we are already using dynamic adapter-nrs.
      
      3) There are 2 places manually instantiating a designware_i2c platform_dev:
      drivers/mfd/intel_quark_i2c_gpio.c
      drivers/mfd/intel-lpss.c
      
      In the intel_quark_i2c_gpio.c case pdev->id is always 0, so switching to
      dynamic adapter-nrs here could lead to the bus-number no longer being
      stable, but the quark X1000 only has 1 i2c-controller, which will also
      be assigned bus-number 0 when using dynamic adapter-nrs.
      
      In the intel-lpss.c case intel_lpss_probe() is called from either
      intel-lpss-acpi.c in which case there always is an ACPI-companion, or
      from intel-lpss-pci.c. In most cases devices handled by intel-lpss-pci.c
      also have an ACPI-companion, so we use a dynamic adapter-nr. But in some
      cases the ACPI-companion is missing and we would use pdev->id (allocated
      from intel_lpss_devid_ida). Devices which use the intel-lpss-pci.c code
      typically have many i2c busses, so using pdev->id in this case may lead
      to a bus-number conflict, triggering a WARN(id < 0, "couldn't get idr")
      in i2c-core-base.c causing an oops an the adapter registration to fail.
      So in this case using non dynamic adapter-nrs is actually undesirable.
      
      One machine on which this oops was triggering is the Apollo Lake based
      Acer TravelMate Spin B118.
      
      TL;DR: Switching to always using dynamic adapter-numbers does not make
      any difference in most cases and in the one case where it does make a
      difference the behavior change is desirable because the old behavior
      caused an oops.
      
      BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1687065Signed-off-by: NHans de Goede <hdegoede@redhat.com>
      Acked-by: NAndy Shevchenko <andriy.shevchenko@linux.intel.com>
      Acked-by: NJarkko Nikula <jarkko.nikula@linux.intel.com>
      Signed-off-by: NWolfram Sang <wsa@the-dreams.de>
      cd86d140
    • H
      i2c: i2c-designware-platdrv: Cleanup setting of the adapter number · 77f3381a
      Hans de Goede 提交于
      i2c-designware-platdrv assumes that if the pdev has an apci-companion
      it should use a dynamic adapter-nr and otherwise it will use pdev->id
      as adapter-nr.
      
      Before this commit the setting of the adapter.nr was somewhat convoluted,
      in the acpi_companion case it was set from dw_i2c_acpi_configure, in the
      non acpi_companion case it was set from dw_i2c_set_fifo_size based on
      tx_fifo_depth not being set yet indicating that dw_i2c_acpi_configure was
      not executed.
      
      This cleans this up, directly setting the adapter-nr from
      dw_i2c_plat_probe for both cases.
      Signed-off-by: NHans de Goede <hdegoede@redhat.com>
      Reviewed-by: NAndy Shevchenko <andriy.shevchenko@linux.intel.com>
      Acked-by: NJarkko Nikula <jarkko.nikula@linux.intel.com>
      Signed-off-by: NWolfram Sang <wsa@the-dreams.de>
      77f3381a
  10. 23 2月, 2019 1 次提交
    • H
      i2c: designware: Do not allow i2c_dw_xfer() calls while suspended · 27515415
      Hans de Goede 提交于
      On most Intel Bay- and Cherry-Trail systems the PMIC is connected over I2C
      and the PMIC is accessed through various means by the _PS0 and _PS3 ACPI
      methods (power on / off methods) of various devices.
      
      This leads to suspend/resume ordering problems where a device may be
      resumed and get its _PS0 method executed before the I2C controller is
      resumed. On Cherry Trail this leads to errors like these:
      
           i2c_designware 808622C1:06: controller timed out
           ACPI Error: AE_ERROR, Returned by Handler for [UserDefinedRegion]
           ACPI Error: Method parse/execution failed \_SB.P18W._ON, AE_ERROR
           video LNXVIDEO:00: Failed to change power state to D0
      
      But on Bay Trail this caused I2C reads to seem to succeed, but they end
      up returning wrong data, which ends up getting written back by the typical
      read-modify-write cycle done to turn on various power-resources.
      
      Debugging the problems caused by this silent data corruption is quite
      nasty. This commit adds a check which disallows i2c_dw_xfer() calls to
      happen until the controller's resume method has completed.
      
      Which turns the silent data corruption into getting these errors in
      dmesg instead:
      
          i2c_designware 80860F41:04: Error i2c_dw_xfer call while suspended
          ACPI Error: AE_ERROR, Returned by Handler for [UserDefinedRegion]
          ACPI Error: Method parse/execution failed \_SB.PCI0.GFX0._PS0, AE_ERROR
      
      Which is much better.
      
      Note the above errors are an example of issues which this patch will
      help to debug, the actual fix requires fixing the suspend order and
      this has been fixed by a different commit.
      
      Note the setting / clearing of the suspended flag in the suspend / resume
      methods is NOT protected by i2c_lock_bus(). This is intentional as these
      methods get called from i2c_dw_xfer() (through pm_runtime_get/put) a nd
      i2c_dw_xfer() is called with the i2c_bus_lock held, so otherwise we would
      deadlock. This means that there is a theoretical race between a non runtime
      suspend and the suspended check in i2c_dw_xfer(), this is not a problem
      since normally we should not hit the race and this check is primarily a
      debugging tool so hitting the check if there are suspend/resume ordering
      problems does not need to be 100% reliable.
      Signed-off-by: NHans de Goede <hdegoede@redhat.com>
      Reviewed-by: NAndy Shevchenko <andriy.shevchenko@linux.intel.com>
      Signed-off-by: NWolfram Sang <wsa@the-dreams.de>
      27515415
  11. 25 10月, 2018 1 次提交
  12. 12 10月, 2018 1 次提交
  13. 07 9月, 2018 1 次提交
  14. 03 9月, 2018 3 次提交
  15. 31 8月, 2018 1 次提交
    • H
      i2c: designware: Re-init controllers with pm_disabled set on resume · 9d9a152e
      Hans de Goede 提交于
      On Bay Trail and Cherry Trail devices we set the pm_disabled flag for I2C
      busses which the OS shares with the PUNIT as these need special handling.
      Until now we called dev_pm_syscore_device(dev, true) for I2C controllers
      with this flag set to keep these I2C controllers always on.
      
      After commit 12864ff8 ("ACPI / LPSS: Avoid PM quirks on suspend and
      resume from hibernation"), this no longer works. This commit modifies
      lpss_iosf_exit_d3_state() to only run if lpss_iosf_enter_d3_state() has ran
      before it, so that it does not run on a resume from hibernate (or from S3).
      
      On these systems the conditions for lpss_iosf_enter_d3_state() to run
      never become true, so lpss_iosf_exit_d3_state() never gets called and
      the 2 LPSS DMA controllers never get forced into D0 mode, instead they
      are left in their default automatic power-on when needed mode.
      
      The not forcing of D0 mode for the DMA controllers enables these systems
      to properly enter S0ix modes, which is a good thing.
      
      But after entering S0ix modes the I2C controller connected to the PMIC
      no longer works, leading to e.g. broken battery monitoring.
      
      The _PS3 method for this I2C controller looks like this:
      
                  Method (_PS3, 0, NotSerialized)  // _PS3: Power State 3
                  {
                      If ((((PMID == 0x04) || (PMID == 0x05)) || (PMID == 0x06)))
                      {
                          Return (Zero)
                      }
      
                      PSAT |= 0x03
                      Local0 = PSAT /* \_SB_.I2C5.PSAT */
                  }
      
      Where PMID = 0x05, so we enter the Return (Zero) path on these systems.
      
      So even if we were to not call dev_pm_syscore_device(dev, true) the
      I2C controller will be left in D0 rather then be switched to D3.
      
      Yet on other Bay and Cherry Trail devices S0ix is not entered unless *all*
      I2C controllers are in D3 mode. This combined with the I2C controller no
      longer working now that we reach S0ix states on these systems leads to me
      believing that the PUNIT itself puts the I2C controller in D3 when all
      other conditions for entering S0ix states are true.
      
      Since now the I2C controller is put in D3 over a suspend/resume we must
      re-initialize it afterwards and that does indeed fix it no longer working.
      
      This commit implements this fix by:
      
      1) Making the suspend_late callback a no-op if pm_disabled is set and
      making the resume_early callback skip the clock re-enable (since it now was
      not disabled) while still doing the necessary I2C controller re-init.
      
      2) Removing the dev_pm_syscore_device(dev, true) call, so that the suspend
      and resume callbacks are actually called. Normally this would cause the
      ACPI pm code to call _PS3 putting the I2C controller in D3, wreaking havoc
      since it is shared with the PUNIT, but in this special case the _PS3 method
      is a no-op so we can safely allow a "fake" suspend / resume.
      
      Fixes: 12864ff8 ("ACPI / LPSS: Avoid PM quirks on suspend and resume ...")
      Link: https://bugzilla.kernel.org/show_bug.cgi?id=200861
      Cc: 4.15+ <stable@vger.kernel.org> # 4.15+
      Signed-off-by: NHans de Goede <hdegoede@redhat.com>
      Reviewed-by: NAndy Shevchenko <andriy.shevchenko@linux.intel.com>
      Acked-by: NJarkko Nikula <jarkko.nikula@linux.intel.com>
      Signed-off-by: NWolfram Sang <wsa@the-dreams.de>
      9d9a152e
  16. 20 8月, 2018 1 次提交
  17. 09 8月, 2018 1 次提交
  18. 10 1月, 2018 2 次提交
    • R
      PM: i2c-designware-platdrv: Optimize power management · 02e45646
      Rafael J. Wysocki 提交于
      Optimize the power management in i2c-designware-platdrv by making it
      set the DPM_FLAG_SMART_SUSPEND and DPM_FLAG_LEAVE_SUSPENDED which
      allows some code to be dropped from its PM callbacks.
      
      First, setting DPM_FLAG_SMART_SUSPEND causes the intel-lpss driver
      to avoid resuming i2c-designware-platdrv devices in its ->prepare
      callback, so they can stay in runtime suspend after that point even
      if the direct-complete feature is not used for them.
      
      It also causes the ACPI PM domain and the PM core to avoid invoking
      "late" and "noirq" suspend callbacks for these devices if they are
      in runtime suspend at the beginning of the "late" phase of device
      suspend during system suspend.  That guarantees dw_i2c_plat_suspend()
      to be called for a device only if it is not in runtime suspend.
      
      Moreover, it causes the device's runtime PM status to be set to
      "active" after calling dw_i2c_plat_resume() for it, so the
      driver doesn't need internal flags to avoid invoking either
      dw_i2c_plat_suspend() or dw_i2c_plat_resume() twice in a row.
      
      Second, setting DPM_FLAG_LEAVE_SUSPENDED enables the optimization
      allowing the device to stay suspended after system resume under
      suitable conditions, so again the driver doesn't need to take
      care of that by itself.
      
      Accordingly, the internal "suspended" and "skip_resume" flags
      used by the driver are not necessary any more, so drop them and
      simplify the driver's PM callbacks.
      
      Additionally, notice that dw_i2c_plat_complete() only needs to
      schedule runtime PM resume for the device if platform firmware
      has been involved in resuming the system, so make it call
      pm_resume_via_firmware() to check that.  Also make it check the
      runtime PM status of the device instead of its direct_complete
      flag which also works if the device remained suspended due to
      the DPM_FLAG_LEAVE_SUSPENDED driver flag.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Acked-by: NJarkko Nikula <jarkko.nikula@linux.intel.com>
      Acked-by: NWolfram Sang <wsa@the-dreams.de>
      Tested-by: NJarkko Nikula <jarkko.nikula@linux.intel.com>
      02e45646
    • R
      PM: i2c-designware-platdrv: Use DPM_FLAG_SMART_PREPARE · 422cb781
      Rafael J. Wysocki 提交于
      Modify i2c-designware-platdrv to set DPM_FLAG_SMART_PREPARE for its
      devices and return 0 from the system suspend ->prepare callback
      if the device has an ACPI companion object in order to tell the PM
      core and middle layers to avoid skipping system suspend/resume
      callbacks for the device in that case (which may be problematic,
      because the device may be accessed during suspend and resume of
      other devices via I2C operation regions then).
      
      Also the pm_runtime_suspended() check in dw_i2c_plat_prepare()
      is not necessary any more, because the core does it when setting
      power.direct_complete for the device, so drop it.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Acked-by: NJarkko Nikula <jarkko.nikula@linux.intel.com>
      Acked-by: NWolfram Sang <wsa@the-dreams.de>
      Tested-by: NJarkko Nikula <jarkko.nikula@linux.intel.com>
      422cb781
  19. 28 11月, 2017 3 次提交
  20. 18 10月, 2017 1 次提交
  21. 05 10月, 2017 2 次提交
    • R
      PM: i2c-designware-platdrv: Suspend/resume at the late/early stages · 54152772
      Rafael J. Wysocki 提交于
      As reported by Rajat Jain, there are problems when ACPI operation
      region handlers or similar, called at the ->resume_early() time, for
      I2C client devices try to access an I2C controller that has already
      been suspended at that point.  To avoid that, move the suspend/resume
      of i2c-designware-platdrv to the late/early stages, respectively.
      
      While at it, avoid resuming the device from runtime suspend in the
      driver's ->suspend callback which isn't particularly nice.  [A better
      approach would be to make the driver track the PM state of the device
      so that it doesn't need to resume it in ->suspend, so implement it.]
      
      First, drop dw_i2c_plat_suspend() added by commit a23318fe (i2c:
      designware: Fix system suspend) and rename dw_i2c_plat_runtime_suspend()
      back to dw_i2c_plat_suspend().
      
      Second, point the driver's ->late_suspend and ->early_resume
      callbacks, rather than its ->suspend and ->resume callbacks,
      to dw_i2c_plat_suspend() and dw_i2c_plat_resume(), respectively,
      so that they are not executed in parallel with each other, for
      example if runtime resume of the device takes place during system
      suspend.
      
      Finally, add "suspended" and "skip_resume" flags to struct dw_i2c_dev
      and make dw_i2c_plat_suspend() and dw_i2c_plat_resume() use them to
      avoid suspending or resuming the device twice in a row and to avoid
      resuming a previously runtime-suspended device during system resume.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Tested-by: NJarkko Nikula <jarkko.nikula@linux.intel.com>
      Tested-by: NMika Westerberg <mika.westerberg@linux.intel.com>
      Tested-by: NJohannes Stezenbach <js@sig21.net>
      Tested-by: NRajat Jain <rajatja@google.com>
      Signed-off-by: NWolfram Sang <wsa@the-dreams.de>
      54152772
    • R
      PM: i2c-designware-platdrv: Clean up PM handling in probe · 126dbc6b
      Rafael J. Wysocki 提交于
      The power management handling in dw_i2c_plat_probe() is somewhat
      messy and it is rather hard to figure out the code intention for
      the case when pm_disabled is set.  In that case, the driver doesn't
      enable runtime PM at all, but in addition to that it calls
      pm_runtime_forbid() as though it wasn't sure if runtime PM might
      be enabled for the device later by someone else.
      
      Although that concern doesn't seem to be actually valid, the
      device is clearly still expected to be PM-capable even in the
      pm_disabled set case, so a better approach would be to enable
      runtime PM for it unconditionally and prevent it from being
      runtime-suspended by using pm_runtime_get_noresume().
      
      Make the driver do that.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Signed-off-by: NWolfram Sang <wsa@the-dreams.de>
      126dbc6b
  22. 01 9月, 2017 1 次提交
  23. 15 8月, 2017 2 次提交
    • J
      i2c: designware: Fix standard mode speed when configuring the slave mode · 4e2d93de
      Jarkko Nikula 提交于
      Code sets bit DW_IC_CON_SPEED_FAST (0x4) always when configuring the slave
      mode. This results incorrect register value DW_IC_CON_SPEED_HIGH (0x6)
      when OR'ed together with DW_IC_CON_SPEED_STD (0x2).
      
      Remove this and let the code set the speed mode bits according to clock
      frequency or default to fast mode.
      Signed-off-by: NJarkko Nikula <jarkko.nikula@linux.intel.com>
      Signed-off-by: NWolfram Sang <wsa@the-dreams.de>
      4e2d93de
    • U
      i2c: designware: Fix system suspend · a23318fe
      Ulf Hansson 提交于
      The commit 8503ff16 ("i2c: designware: Avoid unnecessary resuming
      during system suspend"), may suggest to the PM core to try out the so
      called direct_complete path for system sleep. In this path, the PM core
      treats a runtime suspended device as it's already in a proper low power
      state for system sleep, which makes it skip calling the system sleep
      callbacks for the device, except for the ->prepare() and the ->complete()
      callbacks.
      
      However, the PM core may unset the direct_complete flag for a parent
      device, in case its child device are being system suspended before. In this
      scenario, the PM core invokes the system sleep callbacks, no matter if the
      device is runtime suspended or not.
      
      Particularly in cases of an existing i2c slave device, the above path is
      triggered, which breaks the assumption that the i2c device is always
      runtime resumed whenever the dw_i2c_plat_suspend() is being called.
      
      More precisely, dw_i2c_plat_suspend() calls clk_core_disable() and
      clk_core_unprepare(), for an already disabled/unprepared clock, leading to
      a splat in the log about clocks calls being wrongly balanced and breaking
      system sleep.
      
      To still allow the direct_complete path in cases when it's possible, but
      also to keep the fix simple, let's runtime resume the i2c device in the
      ->suspend() callback, before continuing to put the device into low power
      state.
      
      Note, in cases when the i2c device is attached to the ACPI PM domain, this
      problem doesn't occur, because ACPI's ->suspend() callback, assigned to
      acpi_subsys_suspend(), already calls pm_runtime_resume() for the device.
      
      It should also be noted that this change does not fix commit 8503ff16
      ("i2c: designware: Avoid unnecessary resuming during system suspend").
      Because for the non-ACPI case, the system sleep support was already broken
      prior that point.
      
      Cc: <stable@vger.kernel.org> # v4.4+
      Signed-off-by: NUlf Hansson <ulf.hansson@linaro.org>
      Acked-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Tested-by: NJohn Stultz <john.stultz@linaro.org>
      Tested-by: NJarkko Nikula <jarkko.nikula@linux.intel.com>
      Acked-by: NJarkko Nikula <jarkko.nikula@linux.intel.com>
      Reviewed-by: NMika Westerberg <mika.westerberg@linux.intel.com>
      Signed-off-by: NWolfram Sang <wsa@the-dreams.de>
      a23318fe
  24. 31 7月, 2017 3 次提交
  25. 28 6月, 2017 1 次提交
  26. 20 6月, 2017 2 次提交