1. 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
  2. 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
  3. 25 10月, 2018 1 次提交
  4. 12 10月, 2018 1 次提交
  5. 07 9月, 2018 1 次提交
  6. 03 9月, 2018 3 次提交
  7. 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
  8. 20 8月, 2018 1 次提交
  9. 09 8月, 2018 1 次提交
  10. 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
  11. 28 11月, 2017 3 次提交
  12. 18 10月, 2017 1 次提交
  13. 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
  14. 01 9月, 2017 1 次提交
  15. 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
  16. 31 7月, 2017 3 次提交
  17. 28 6月, 2017 1 次提交
  18. 20 6月, 2017 3 次提交
  19. 23 5月, 2017 1 次提交
  20. 22 5月, 2017 1 次提交
  21. 19 5月, 2017 1 次提交
  22. 27 4月, 2017 1 次提交
  23. 20 4月, 2017 1 次提交
  24. 22 3月, 2017 2 次提交
    • H
      i2c: designware: Disable pm for PMIC i2c-bus even if there is no _SEM method · a3d411fb
      Hans de Goede 提交于
      Cherrytrail devices use the dw i2c-bus with uid 7 to access their PMIC.
      Even if the i2c-bus to the PMIC is not shared with the SoC's P-Unit
      and i2c-designware-baytrail.c thus does not set the pm_disabled flag,
      we still need to disable pm so that ACPI PMIC opregions can access the
      PMIC during late-suspend and early-resume.
      
      This fixes errors like these blocking suspend:
      
        i2c_designware 808622C1:06: timeout waiting for bus ready
        ACPI Exception: AE_ERROR, Returned by Handler for [UserDefinedRegion]
        acpi 80860F14:02: Failed to change power state to D3hot
        PM: late suspend of devices failed
      Signed-off-by: NHans de Goede <hdegoede@redhat.com>
      Acked-by: NJarkko Nikula <jarkko.nikula@linux.intel.com>
      Signed-off-by: NWolfram Sang <wsa@the-dreams.de>
      a3d411fb
    • H
      i2c: designware: Never suspend i2c-busses used for accessing the system PMIC · 41c80b8a
      Hans de Goede 提交于
      Currently we are already setting a pm_runtime_disabled flag and disabling
      runtime-pm for i2c-busses used for accessing the system PMIC on x86.
      But this is not enough, there are ACPI opregions which may want to access
      the PMIC during late-suspend and early-resume, so we need to completely
      disable pm to be safe.
      
      This commit renames the flag from pm_runtime_disabled to pm_disabled and
      adds the following new behavior if the flag is set:
      
      1) Call dev_pm_syscore_device(dev, true) which disables normal suspend /
         resume and remove the pm_runtime_disabled check from dw_i2c_plat_resume
         since that will now never get called. This fixes suspend_late handlers
         which use ACPI PMIC opregions causing errors like these:
      
        PM: Suspending system (freeze)
        PM: suspend of devices complete after 1127.751 msecs
        i2c_designware 808622C1:06: timeout waiting for bus ready
        ACPI Exception: AE_ERROR, Returned by Handler for [UserDefinedRegion]
        acpi 80860F14:02: Failed to change power state to D3hot
        PM: late suspend of devices failed
      
      2) Set IRQF_NO_SUSPEND irq flag. This fixes resume_early handlers which
         handlers which use ACPI PMIC opregions causing errors like these:
      
        PM: resume from suspend-to-idle
        i2c_designware 808622C1:06: controller timed out
        ACPI Exception: AE_ERROR, Returned by Handler for [UserDefinedRegion]
      Signed-off-by: NHans de Goede <hdegoede@redhat.com>
      Acked-by: NJarkko Nikula <jarkko.nikula@linux.intel.com>
      Signed-off-by: NWolfram Sang <wsa@the-dreams.de>
      41c80b8a
  25. 09 3月, 2017 1 次提交
  26. 02 3月, 2017 2 次提交