1. 04 May, 2016 4 commits
    • Peter Rosin's avatar
    • Peter Rosin's avatar
      i2c: mux: relax locking of the top i2c adapter during mux-locked muxing · 6ef91fcc
      Peter Rosin authored
      With a i2c topology like the following
      
                             GPIO ---|  ------ BAT1
                              |      v /
         I2C  -----+----------+---- MUX
                   |                   \
                 EEPROM                 ------ BAT2
      
      there is a locking problem with the GPIO controller since it is a client
      on the same i2c bus that it muxes. Transfers to the mux clients (e.g. BAT1)
      will lock the whole i2c bus prior to attempting to switch the mux to the
      correct i2c segment. In the above case, the GPIO device is an I/O expander
      with an i2c interface, and since the GPIO subsystem knows nothing (and
      rightfully so) about the lockless needs of the i2c mux code, this results
      in a deadlock when the GPIO driver issues i2c transfers to modify the
      mux.
      
      So, observing that while it is needed to have the i2c bus locked during the
      actual MUX update in order to avoid random garbage on the slave side, it
      is not strictly a must to have it locked over the whole sequence of a full
      select-transfer-deselect mux client operation. The mux itself needs to be
      locked, so transfers to clients behind the mux are serialized, and the mux
      needs to be stable during all i2c traffic (otherwise individual mux slave
      segments might see garbage, or worse).
      
      Introduce this new locking concept as "mux-locked" muxes, and call the
      pre-existing mux locking scheme "parent-locked".
      
      Modify the i2c mux locking so that muxes that are "mux-locked" locks only
      the muxes on the parent adapter instead of the whole i2c bus when there is
      a transfer to the slave side of the mux. This lock serializes transfers to
      the slave side of the muxes on the parent adapter.
      
      Add code to i2c-mux-gpio and i2c-mux-pinctrl that checks if all involved
      gpio/pinctrl devices have a parent that is an i2c adapter in the same
      adapter tree that is muxed, and request a "mux-locked mux" if that is the
      case.
      
      Modify the select-transfer-deselect code for "mux-locked" muxes so
      that each of the select-transfer-deselect ops locks the mux parent
      adapter individually.
      Signed-off-by: default avatarPeter Rosin <peda@axentia.se>
      Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
      6ef91fcc
    • Peter Rosin's avatar
      i2c: muxes always lock the parent adapter · fa96f0cb
      Peter Rosin authored
      Instead of checking for i2c parent adapters for every lock/unlock, simply
      override the locking for muxes to always lock/unlock the parent adapter
      directly.
      Signed-off-by: default avatarPeter Rosin <peda@axentia.se>
      Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
      fa96f0cb
    • Peter Rosin's avatar
      i2c: allow adapter drivers to override the adapter locking · 8320f495
      Peter Rosin authored
      Add i2c_lock_bus() and i2c_unlock_bus(), which call the new lock_bus and
      unlock_bus ops in the adapter. These funcs/ops take an additional flags
      argument that indicates for what purpose the adapter is locked.
      
      There are two flags, I2C_LOCK_ROOT_ADAPTER and I2C_LOCK_SEGMENT, but they
      are both implemented the same. For now. Locking the root adapter means
      that the whole bus is locked, locking the segment means that only the
      current bus segment is locked (i.e. i2c traffic on the parent side of
      a mux is still allowed even if the child side of the mux is locked).
      
      Also support a trylock_bus op (but no function to call it, as it is not
      expected to be needed outside of the i2c core).
      
      Implement i2c_lock_adapter/i2c_unlock_adapter in terms of the new locking
      scheme (i.e. lock with the I2C_LOCK_ROOT_ADAPTER flag).
      
      Locking the root adapter and locking the segment is the same thing for
      all root adapters (e.g. in the normal case of a simple topology with no
      i2c muxes). The two locking variants are also the same for traditional
      muxes (aka parent-locked muxes). These muxes traverse the tree, locking
      each level as they go until they reach the root. This patch is preparatory
      for a later patch in the series introducing mux-locked muxes, which behave
      differently depending on the requested locking. Since all current users
      are using i2c_lock_adapter, which is a wrapper for I2C_LOCK_ROOT_ADAPTER,
      we only need to annotate the calls that will not need to lock the root
      adapter for mux-locked muxes. I.e. the instances that needs to use
      I2C_LOCK_SEGMENT instead of i2c_lock_adapter/I2C_LOCK_ROOT_ADAPTER. Those
      instances are in the i2c_transfer and i2c_smbus_xfer functions, so that
      mux-locked muxes can single out normal i2c accesses to its slave side
      and adjust the locking for those accesses.
      Signed-off-by: default avatarPeter Rosin <peda@axentia.se>
      Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
      8320f495
  2. 27 Apr, 2016 6 commits
  3. 26 Apr, 2016 4 commits
    • Javier Martinez Canillas's avatar
      i2c: nforce2: Use IS_ENABLED() instead of checking for built-in or module · dd485951
      Javier Martinez Canillas authored
      The IS_ENABLED() macro checks if a Kconfig symbol has been enabled either
      built-in or as a module, use that macro instead of open coding the same.
      Signed-off-by: default avatarJavier Martinez Canillas <javier@osg.samsung.com>
      Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
      dd485951
    • Oleksij Rempel's avatar
      i2c: imx: reduce load by using usleep_range instead of udelay · 2b899f34
      Oleksij Rempel authored
      Documentation/timers/timers-howto.txt recommends to use
      usleep_range on delays > 10usec. According to my test results
      with Neonode zForce touchscreen driver, usleep_range indeed
      reduces CPU load.
      
      Stats collected with "./perf record -a -g -F 1000 sleep 10"
      
      i2c-imx with udelay(50):
      34.19% 0.00% irq/220-Neonode [kernel.kallsyms] [k] irq_thread
          ---irq_thread
             |--33.75%--irq_thread_fn
             |    |--19.27%--0x7f08a878
             |    |     i2c_master_recv
             |    |     i2c_transfer
             |    |     __i2c_transfer
             |    |     i2c_imx_xfer
             |    |     |--11.71%--i2c_imx_trx_complete
             |    |     |--5.70%--i2c_imx_start <<<<----------------
             |    |     |     |--5.38%--__timer_const_udelay
             |    |     |     |      __timer_delay
             |    |     |     |      --5.07%--read_current_timer
      
      i2c-imx with usleep_range(50,100)
      29.08% 0.00% irq/220-Neonode  [kernel.kallsyms] [k] irq_thread
          ---irq_thread
             |--28.89%--irq_thread_fn
             |    |--17.21%--0x7f08a878
             |    |     i2c_master_recv
             |    |     |--17.14%--i2c_transfer
             |    |     |     __i2c_transfer
             |    |     |     i2c_imx_xfer
             |    |     |     |--14.29%--i2c_imx_trx_complete
             |    |     |     |--1.42%--i2c_imx_start <<<<----------
             |    |     |     |      |--0.71%--usleep_range
             |    |     |     |      |--0.53%--i2c_imx_bus_busy
      Signed-off-by: default avatarOleksij Rempel <linux@rempel-privat.de>
      Signed-off-by: default avatarDirk Behme <dirk.behme@de.bosch.com>
      Reviewed-by: default avatarVladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
      Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
      2b899f34
    • Peter Swain's avatar
      i2c: octeon: Improve performance if interrupt is early · 1bb1ff3e
      Peter Swain authored
      There is a race between the TWSI interrupt and the condition
      that is required before proceeding:
      
      Low-level: interrupt flag bit must be set
      High-level controller: valid bit must be clear
      
      If the interrupt comes too early and the condition is not met
      the wait will time out, and the transfer is aborted leading
      to very poor performance.
      
      To avoid this race retry for the condition ~80 µs later.
      The retry is avoided on the very first invocation of
      wait_event_timeout() (which tests the condition before entering
      the wait and is therefore always wrong in this case).
      
      EEPROM reads on 100kHz i2c now measure ~5.2kB/s, about 1/2 what's
      achievable, and much better than the worst-case 100 bytes/sec before.
      
      While at it remove the debug print from the low-level wait function.
      Signed-off-by: default avatarPeter Swain <pswain@cavium.com>
      Signed-off-by: default avatarJan Glauber <jglauber@cavium.com>
      Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
      1bb1ff3e
    • Jan Glauber's avatar
      i2c: octeon: Remove zero-length message support · 392d01de
      Jan Glauber authored
      Zero-length message support (SMBUS QUICK or i2c) never worked with
      the Octeon hardware. Disable SMBUS QUICK support and bail out in
      case of a zero-length i2c request.
      
      After this change 'i2c-detect -q' will return an error on Octeon but
      the previously reported results were wrong anyway.
      Signed-off-by: default avatarJan Glauber <jglauber@cavium.com>
      Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
      392d01de
  4. 25 Apr, 2016 10 commits
  5. 24 Apr, 2016 5 commits
  6. 22 Apr, 2016 11 commits