1. 15 10月, 2019 5 次提交
  2. 08 10月, 2019 1 次提交
    • V
      spi: Add a PTP system timestamp to the transfer structure · b42faeee
      Vladimir Oltean 提交于
      SPI is one of the interfaces used to access devices which have a POSIX
      clock driver (real time clocks, 1588 timers etc). The fact that the SPI
      bus is slow is not what the main problem is, but rather the fact that
      drivers don't take a constant amount of time in transferring data over
      SPI. When there is a high delay in the readout of time, there will be
      uncertainty in the value that has been read out of the peripheral.
      When that delay is constant, the uncertainty can at least be
      approximated with a certain accuracy which is fine more often than not.
      
      Timing jitter occurs all over in the kernel code, and is mainly caused
      by having to let go of the CPU for various reasons such as preemption,
      servicing interrupts, going to sleep, etc. Another major reason is CPU
      dynamic frequency scaling.
      
      It turns out that the problem of retrieving time from a SPI peripheral
      with high accuracy can be solved by the use of "PTP system
      timestamping" - a mechanism to correlate the time when the device has
      snapshotted its internal time counter with the Linux system time at that
      same moment. This is sufficient for having a precise time measurement -
      it is not necessary for the whole SPI transfer to be transmitted "as
      fast as possible", or "as low-jitter as possible". The system has to be
      low-jitter for a very short amount of time to be effective.
      
      This patch introduces a PTP system timestamping mechanism in struct
      spi_transfer. This is to be used by SPI device drivers when they need to
      know the exact time at which the underlying device's time was
      snapshotted. More often than not, SPI peripherals have a very exact
      timing for when their SPI-to-interconnect bridge issues a transaction
      for snapshotting and reading the time register, and that will be
      dependent on when the SPI-to-interconnect bridge figures out that this
      is what it should do, aka as soon as it sees byte N of the SPI transfer.
      Since spi_device drivers are the ones who'd know best how the peripheral
      behaves in this regard, expose a mechanism in spi_transfer which allows
      them to specify which word (or word range) from the transfer should be
      timestamped.
      
      Add a default implementation of the PTP system timestamping in the SPI
      core. This is not going to be satisfactory performance-wise, but should
      at least increase the likelihood that SPI device drivers will use PTP
      system timestamping in the future.
      There are 3 entry points from the core towards the SPI controller
      drivers:
      
      - transfer_one: The driver is passed individual spi_transfers to
        execute. This is the easiest to timestamp.
      
      - transfer_one_message: The core passes the driver an entire spi_message
        (a potential batch of spi_transfers). The core puts the same pre and
        post timestamp to all transfers within a message. This is not ideal,
        but nothing better can be done by default anyway, since the core has
        no insight into how the driver batches the transfers.
      
      - transfer: Like transfer_one_message, but for unqueued drivers (i.e.
        the driver implements its own queue scheduling).
      Signed-off-by: NVladimir Oltean <olteanv@gmail.com>
      Link: https://lore.kernel.org/r/20190905010114.26718-3-olteanv@gmail.comSigned-off-by: NMark Brown <broonie@kernel.org>
      b42faeee
  3. 17 6月, 2019 1 次提交
  4. 23 5月, 2019 1 次提交
  5. 13 5月, 2019 1 次提交
  6. 08 5月, 2019 2 次提交
    • M
      spi: core: allow defining time that cs is deasserted as a multiple of SCK · d5864e5b
      Martin Sperl 提交于
      Support setting a delay between cs assert and deassert as
      a multiple of spi clock length.
      Signed-off-by: NMartin Sperl <kernel@martin.sperl.org>
      Signed-off-by: NMark Brown <broonie@kernel.org>
      d5864e5b
    • M
      spi: core: allow defining time that cs is deasserted · 0ff2de8b
      Martin Sperl 提交于
      For some SPI devices that support speed_hz > 1MHz the default 10 us delay
      when cs_change = 1 is typically way to long and may result in poor spi bus
      utilization.
      
      This patch makes it possible to control the delay at micro or nano second
      resolution on a per spi_transfer basis. It even allows an "as fast as
      possible" mode with:
          xfer.cs_change_delay_unit = SPI_DELAY_UNIT_NSECS;
          xfer.cs_change_delay = 0;
      
      The delay code is shared between delay_usecs and cs_change_delay for
      consistency and reuse, so in the future this change_delay_unit could also
      apply to delay_usec as well.
      
      Note that on slower SOCs/CPU actually reaching ns deasserts on cs is not
      realistic as the gpio overhead alone (without any delays added ) may
      already leave cs deasserted for more than 1us - at least on a raspberry pi.
      But at the very least this way we can keep it as short as possible.
      Signed-off-by: NMartin Sperl <kernel@martin.sperl.org>
      Signed-off-by: NMark Brown <broonie@kernel.org>
      0ff2de8b
  7. 02 5月, 2019 1 次提交
  8. 12 4月, 2019 1 次提交
  9. 08 4月, 2019 1 次提交
  10. 14 3月, 2019 1 次提交
  11. 12 3月, 2019 1 次提交
  12. 31 1月, 2019 1 次提交
    • J
      spi: support inter-word delay requirement for devices · b7bb367a
      Jonas Bonn 提交于
      Some devices are slow and cannot keep up with the SPI bus and therefore
      require a short delay between words of the SPI transfer.
      
      The example of this that I'm looking at is a SAMA5D2 with a minimum SPI
      clock of 400kHz talking to an AVR-based SPI slave.  The AVR cannot put
      bytes on the bus fast enough to keep up with the SoC's SPI controller
      even at the lowest bus speed.
      
      This patch introduces the ability to specify a required inter-word
      delay for SPI devices.  It is up to the controller driver to configure
      itself accordingly in order to introduce the requested delay.
      
      Note that, for spi_transfer, there is already a field word_delay that
      provides similar functionality.  This field, however, is specified in
      clock cycles (and worse, SPI controller cycles, not SCK cycles); that
      makes this value dependent on the master clock instead of the device
      clock for which the delay is intended to provide some relief.  This
      patch leaves this old word_delay in place and provides a time-based
      word_delay_us alongside it; the new field fits in the struct padding
      so struct size is constant.  There is only one in-kernel user of the
      word_delay field and presumably that driver could be reworked to use
      the time-based value instead.
      
      The time-based delay is limited to 8 bits as these delays are intended
      to be short.  The SAMA5D2 that I've tested this on limits delays to a
      maximum of ~100us, which is already many word-transfer periods even at
      the minimum transfer speed supported by the controller.
      Signed-off-by: NJonas Bonn <jonas@norrbonn.se>
      CC: Mark Brown <broonie@kernel.org>
      CC: Rob Herring <robh+dt@kernel.org>
      CC: Mark Rutland <mark.rutland@arm.com>
      CC: linux-spi@vger.kernel.org
      CC: devicetree@vger.kernel.org
      Signed-off-by: NMark Brown <broonie@kernel.org>
      b7bb367a
  13. 24 1月, 2019 1 次提交
  14. 10 1月, 2019 1 次提交
    • M
      spi: core: avoid waking pump thread from spi_sync instead run teardown delayed · 412e6037
      Martin Sperl 提交于
      When spi_sync is running alone with no other spi devices connected
      to the bus the worker thread is woken during spi_finalize_current_message
      to run the teardown code every time.
      
      This is totally unnecessary in the case that there is no message queued.
      
      On a multi-core system this results in one wakeup of the thread for each
      spi_message processed via spi_sync where in most cases the teardown does
      not happen as the hw is already in use.
      
      This patch now delays the teardown by 1 second by using a separate
      kthread_delayed_work for the teardown.
      
      This avoids waking the kthread too often.
      
      For spi_sync transfers in a tight loop (say 40k messages/s) this
      avoids the penalty of waking the worker thread 40k times/s.
      On a rasperry pi 3 with 4 cores the results in 32% of a single core
      only to find out that there is nothing in the queue and it can go back
      to sleep.
      
      With this patch applied the spi-worker is woken exactly once: after
      the load finishes and the spi bus is idle for 1 second.
      
      I believe I have also seen situations where during a spi_sync loop
      the worker thread (triggered by the last message finished) is slightly
      faster and _wins_ the race to process the message, so we are actually
      running the kthread and letting it do some work...
      
      This is also no longer observed with this patch applied as.
      
      Tested with a new CAN controller driver for the mcp2517fd which
      uses spi_sync for interrupt handling and spi_async for scheduling
      of can frames for transmission (in a different thread)
      
      Some statistics when receiving 100000 CAN frames with the mcp25xxfd driver
      on a Raspberry pi 3:
      
      without the patch:
      ------------------
      root@raspcm3:~# for x in $(pgrep spi0) $(pgrep irq/94-mcp25xxf) ; do awk '{printf "%-20s %6i\n", $2,$15}' /proc/$x/stat; done
      (spi0)                    5
      (irq/94-mcp25xxf)         0
      root@raspcm3:~# vmstat 1
      procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
       r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
       1  0      0 821960  13592  50848    0    0    80     2 1986  105  1  2 97  0  0
       0  0      0 821968  13592  50876    0    0     0     0 8046   30  0  0 100  0  0
       0  0      0 821936  13592  50876    0    0     0     0 8032   24  0  0 100  0  0
       0  0      0 821936  13592  50876    0    0     0     0 8035   30  0  0 100  0  0
       0  0      0 821936  13592  50876    0    0     0     0 8033   22  0  0 100  0  0
       2  0      0 821936  13592  50876    0    0     0     0 11598 7129  0  3 97  0  0
       1  0      0 821872  13592  50876    0    0     0     0 37741 59003  0 31 69  0  0
       2  0      0 821840  13592  50876    0    0     0     0 37762 59078  0 29 71  0  0
       2  0      0 821776  13592  50876    0    0     0     0 37593 58792  0 28 72  0  0
       1  0      0 821744  13592  50876    0    0     0     0 37642 58881  0 30 70  0  0
       2  0      0 821680  13592  50876    0    0     0     0 37490 58602  0 27 73  0  0
       1  0      0 821648  13592  50876    0    0     0     0 37412 58418  0 29 71  0  0
       1  0      0 821584  13592  50876    0    0     0     0 37337 58288  0 27 73  0  0
       1  0      0 821552  13592  50876    0    0     0     0 37584 58774  0 27 73  0  0
       0  0      0 821520  13592  50876    0    0     0     0 18363 20566  0  9 91  0  0
       0  0      0 821520  13592  50876    0    0     0     0 8037   32  0  0 100  0  0
       0  0      0 821520  13592  50876    0    0     0     0 8031   23  0  0 100  0  0
       0  0      0 821520  13592  50876    0    0     0     0 8034   26  0  0 100  0  0
       0  0      0 821520  13592  50876    0    0     0     0 8033   24  0  0 100  0  0
      ^C
      root@raspcm3:~# for x in $(pgrep spi0) $(pgrep irq/94-mcp25xxf) ; do awk '{printf "%-20s %6i\n", $2,$15}' /proc/$x/stat; done
      (spi0)                  228
      (irq/94-mcp25xxf)       794
      root@raspcm3:~# cat /proc/interrupts
                 CPU0       CPU1       CPU2       CPU3
       17:         34          0          0          0  ARMCTRL-level   1 Edge      3f00b880.mailbox
       27:          1          0          0          0  ARMCTRL-level  35 Edge      timer
       33:    1416870          0          0          0  ARMCTRL-level  41 Edge      3f980000.usb, dwc2_hsotg:usb1
       34:          1          0          0          0  ARMCTRL-level  42 Edge      vc4
       35:          0          0          0          0  ARMCTRL-level  43 Edge      3f004000.txp
       40:       1753          0          0          0  ARMCTRL-level  48 Edge      DMA IRQ
       42:         11          0          0          0  ARMCTRL-level  50 Edge      DMA IRQ
       44:         11          0          0          0  ARMCTRL-level  52 Edge      DMA IRQ
       45:          0          0          0          0  ARMCTRL-level  53 Edge      DMA IRQ
       66:          0          0          0          0  ARMCTRL-level  74 Edge      vc4 crtc
       69:          0          0          0          0  ARMCTRL-level  77 Edge      vc4 crtc
       70:          0          0          0          0  ARMCTRL-level  78 Edge      vc4 crtc
       77:         20          0          0          0  ARMCTRL-level  85 Edge      3f205000.i2c, 3f804000.i2c, 3f805000.i2c
       78:       6346          0          0          0  ARMCTRL-level  86 Edge      3f204000.spi
       80:        205          0          0          0  ARMCTRL-level  88 Edge      mmc0
       81:        493          0          0          0  ARMCTRL-level  89 Edge      uart-pl011
       89:          0          0          0          0  bcm2836-timer   0 Edge      arch_timer
       90:       4291       3821       2180       1649  bcm2836-timer   1 Edge      arch_timer
       94:      14289          0          0          0  pinctrl-bcm2835  16 Level     mcp25xxfd
      IPI0:          0          0          0          0  CPU wakeup interrupts
      IPI1:          0          0          0          0  Timer broadcast interrupts
      IPI2:       3645     242371       7919       1328  Rescheduling interrupts
      IPI3:        112        543        273        194  Function call interrupts
      IPI4:          0          0          0          0  CPU stop interrupts
      IPI5:          1          0          0          0  IRQ work interrupts
      IPI6:          0          0          0          0  completion interrupts
      Err:          0
      
      top shows 93% for the mcp25xxfd interrupt handler, 31% for spi0.
      
      with the patch:
      ---------------
      root@raspcm3:~# for x in $(pgrep spi0) $(pgrep irq/94-mcp25xxf) ; do awk '{printf "%-20s %6i\n", $2,$15}' /proc/$x/stat; done
      (spi0)                    0
      (irq/94-mcp25xxf)         0
      root@raspcm3:~# vmstat 1
      procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
       0  0      0 804768  13584  62628    0    0     0     0 8038   24  0  0 100  0  0
       0  0      0 804768  13584  62628    0    0     0     0 8042   25  0  0 100  0  0
       1  0      0 804704  13584  62628    0    0     0     0 9603 2967  0 20 80  0  0
       1  0      0 804672  13584  62628    0    0     0     0 9828 3380  0 24 76  0  0
       1  0      0 804608  13584  62628    0    0     0     0 9823 3375  0 23 77  0  0
       1  0      0 804608  13584  62628    0    0     0    12 9829 3394  0 23 77  0  0
       1  0      0 804544  13584  62628    0    0     0     0 9816 3362  0 22 78  0  0
       1  0      0 804512  13584  62628    0    0     0     0 9817 3367  0 23 77  0  0
       1  0      0 804448  13584  62628    0    0     0     0 9822 3370  0 22 78  0  0
       1  0      0 804416  13584  62628    0    0     0     0 9815 3367  0 23 77  0  0
       0  0      0 804352  13584  62628    0    0     0    84 9222 2250  0 14 86  0  0
       0  0      0 804352  13592  62620    0    0     0    24 8131  209  0  0 93  7  0
       0  0      0 804320  13592  62628    0    0     0     0 8041   27  0  0 100  0  0
       0  0      0 804352  13592  62628    0    0     0     0 8040   26  0  0 100  0  0
      root@raspcm3:~# for x in $(pgrep spi0) $(pgrep irq/94-mcp25xxf) ; do awk '{printf "%-20s %6i\n", $2,$15}' /proc/$x/stat; done
      (spi0)                    0
      (irq/94-mcp25xxf)       767
      root@raspcm3:~# cat /proc/interrupts
                 CPU0       CPU1       CPU2       CPU3
       17:         29          0          0          0  ARMCTRL-level   1 Edge      3f00b880.mailbox
       27:          1          0          0          0  ARMCTRL-level  35 Edge      timer
       33:    1024412          0          0          0  ARMCTRL-level  41 Edge      3f980000.usb, dwc2_hsotg:usb1
       34:          1          0          0          0  ARMCTRL-level  42 Edge      vc4
       35:          0          0          0          0  ARMCTRL-level  43 Edge      3f004000.txp
       40:       1773          0          0          0  ARMCTRL-level  48 Edge      DMA IRQ
       42:         11          0          0          0  ARMCTRL-level  50 Edge      DMA IRQ
       44:         11          0          0          0  ARMCTRL-level  52 Edge      DMA IRQ
       45:          0          0          0          0  ARMCTRL-level  53 Edge      DMA IRQ
       66:          0          0          0          0  ARMCTRL-level  74 Edge      vc4 crtc
       69:          0          0          0          0  ARMCTRL-level  77 Edge      vc4 crtc
       70:          0          0          0          0  ARMCTRL-level  78 Edge      vc4 crtc
       77:         20          0          0          0  ARMCTRL-level  85 Edge      3f205000.i2c, 3f804000.i2c, 3f805000.i2c
       78:       6417          0          0          0  ARMCTRL-level  86 Edge      3f204000.spi
       80:        237          0          0          0  ARMCTRL-level  88 Edge      mmc0
       81:        489          0          0          0  ARMCTRL-level  89 Edge      uart-pl011
       89:          0          0          0          0  bcm2836-timer   0 Edge      arch_timer
       90:       4048       3704       2383       1892  bcm2836-timer   1 Edge      arch_timer
       94:      14287          0          0          0  pinctrl-bcm2835  16 Level     mcp25xxfd
      IPI0:          0          0          0          0  CPU wakeup interrupts
      IPI1:          0          0          0          0  Timer broadcast interrupts
      IPI2:       2361       2948       7890       1616  Rescheduling interrupts
      IPI3:         65        617        301        166  Function call interrupts
      IPI4:          0          0          0          0  CPU stop interrupts
      IPI5:          1          0          0          0  IRQ work interrupts
      IPI6:          0          0          0          0  completion interrupts
      Err:          0
      top shows 91% for the mcp25xxfd interrupt handler, 0% for spi0
      
      So we see that spi0 is no longer getting scheduled wasting CPU cycles
      There are a lot less context switches and corresponding Rescheduling interrupts
      All of these show that this improves efficiency of the system and reduces
      CPU utilization.
      Signed-off-by: NMartin Sperl <kernel@martin.sperl.org>
      Signed-off-by: NMark Brown <broonie@kernel.org>
      412e6037
  15. 09 1月, 2019 1 次提交
    • L
      spi: Optionally use GPIO descriptors for CS GPIOs · f3186dd8
      Linus Walleij 提交于
      This augments the SPI core to optionally use GPIO descriptors
      for chip select on a per-master-driver opt-in basis.
      
      Drivers using this will rely on the SPI core to look up
      GPIO descriptors associated with the device, such as
      when using device tree or board files with GPIO descriptor
      tables.
      
      When getting descriptors from the device tree, this will in
      turn activate the code in gpiolib that was
      added in commit 6953c57a
      ("gpio: of: Handle SPI chipselect legacy bindings")
      which means that these descriptors are aware of the active
      low semantics that is the default for SPI CS GPIO lines
      and we can assume that all of these are "active high" and
      thus assign SPI_CS_HIGH to all CS lines on the DT path.
      
      The previously used gpio_set_value() would call down into
      gpiod_set_raw_value() and ignore the polarity inversion
      semantics.
      
      It seems like many drivers go to great lengths to set up the
      CS GPIO line as non-asserted, respecting SPI_CS_HIGH. We pull
      this out of the SPI drivers and into the core, and by simply
      requesting the line as GPIOD_OUT_LOW when retrieveing it from
      the device and relying on the gpiolib to handle any inversion
      semantics. This way a lot of code can be simplified and
      removed in each converted driver.
      
      The end goal after dealing with each driver in turn, is to
      delete the non-descriptor path (of_spi_register_master() for
      example) and let the core deal with only descriptors.
      
      The different SPI drivers have complex interactions with the
      core so we cannot simply change them all over, we need to use
      a stepwise, bisectable approach so that each driver can be
      converted and fixed in isolation.
      
      This patch has the intended side effect of adding support for
      ACPI GPIOs as it starts relying on gpiod_get_*() to get
      the GPIO handle associated with the device.
      
      Cc: Linuxarm <linuxarm@huawei.com>
      Acked-by: NJonathan Cameron <jonathan.cameron@huawei.com>
      Tested-by: NFangjian (Turing) <f.fangjian@huawei.com>
      Signed-off-by: NLinus Walleij <linus.walleij@linaro.org>
      Signed-off-by: NMark Brown <broonie@kernel.org>
      f3186dd8
  16. 04 12月, 2018 1 次提交
  17. 08 11月, 2018 1 次提交
  18. 10 10月, 2018 1 次提交
  19. 28 9月, 2018 2 次提交
  20. 18 9月, 2018 1 次提交
  21. 29 8月, 2018 1 次提交
  22. 11 5月, 2018 2 次提交
  23. 01 12月, 2017 1 次提交
  24. 14 6月, 2017 1 次提交
    • G
      spi: Generalize SPI "master" to "controller" · 8caab75f
      Geert Uytterhoeven 提交于
      Now struct spi_master is used for both SPI master and slave controllers,
      it makes sense to rename it to struct spi_controller, and replace
      "master" by "controller" where appropriate.
      
      For now this conversion is done for SPI core infrastructure only.
      Wrappers are provided for backwards compatibility, until all SPI drivers
      have been converted.
      
      Noteworthy details:
        - SPI_MASTER_GPIO_SS is retained, as it only makes sense for SPI
          master controllers,
        - spi_busnum_to_master() is retained, as it looks up masters only,
        - A new field spi_device.controller is added, but spi_device.master is
          retained for compatibility (both are always initialized by
          spi_alloc_device()),
        - spi_flash_read() is used by SPI masters only.
      Signed-off-by: NGeert Uytterhoeven <geert+renesas@glider.be>
      Signed-off-by: NMark Brown <broonie@kernel.org>
      8caab75f
  25. 26 5月, 2017 1 次提交
    • G
      spi: core: Add support for registering SPI slave controllers · 6c364062
      Geert Uytterhoeven 提交于
      Add support for registering SPI slave controllers using the existing SPI
      master framework:
        - SPI slave controllers must use spi_alloc_slave() instead of
          spi_alloc_master(), and should provide an additional callback
          "slave_abort" to abort an ongoing SPI transfer request,
        - SPI slave controllers are added to a new "spi_slave" device class,
        - SPI slave handlers can be bound to the SPI slave device represented
          by an SPI slave controller using a DT child node named "slave",
        - Alternatively, (un)binding an SPI slave handler to the SPI slave
          device represented by an SPI slave controller can be done by
          (un)registering the slave device through a sysfs virtual file named
          "slave".
      
      From the point of view of an SPI slave protocol handler, an SPI slave
      controller looks almost like an ordinary SPI master controller. The only
      exception is that a transfer request will block on the remote SPI
      master, and may be cancelled using spi_slave_abort().
      Signed-off-by: NGeert Uytterhoeven <geert+renesas@glider.be>
      Signed-off-by: NMark Brown <broonie@kernel.org>
      6c364062
  26. 22 4月, 2017 1 次提交
  27. 29 3月, 2017 1 次提交
  28. 06 3月, 2017 1 次提交
  29. 21 10月, 2016 1 次提交
    • T
      spi: Add Flag to Enable Slave Select with GPIO Chip Select. · 8eee6b9d
      Thor Thayer 提交于
      Some SPI masters require slave selection before the transfer
      can begin [1]. The SPI framework currently selects the chip using
      either 1) the internal CS mechanism or 2) the GPIO CS, but not both.
      
      This patch adds a new master->flags define to indicate both the GPIO
      CS and the internal chip select mechanism should be used.
      
      Tested On:
          Altera CycloneV development kit
          Compile tested for build errors on x86_64 (allyesconfigs)
      
      [1] DesignWare dw_apb_ssi Databook, Version 3.20a (page 39)
      Signed-off-by: NThor Thayer <tthayer@opensource.altera.com>
      Signed-off-by: NMark Brown <broonie@kernel.org>
      8eee6b9d
  30. 11 10月, 2016 1 次提交
    • T
      spi: Add Flag to Enable Slave Select with GPIO Chip Select. · 6b1576aa
      Thor Thayer 提交于
      Some SPI masters require slave selection before the transfer
      can begin [1]. The SPI framework currently selects the chip using
      either 1) the internal CS mechanism or 2) the GPIO CS, but not both.
      
      This patch adds a new master->flags define to indicate both the GPIO
      CS and the internal chip select mechanism should be used.
      
      Tested On:
          Altera CycloneV development kit
          Compile tested for build errors on x86_64 (allyesconfigs)
      
      [1] DesignWare dw_apb_ssi Databook, Version 3.20a (page 39)
      Signed-off-by: NThor Thayer <tthayer@opensource.altera.com>
      Signed-off-by: NMark Brown <broonie@kernel.org>
      6b1576aa
  31. 16 9月, 2016 1 次提交
  32. 18 8月, 2016 1 次提交
  33. 25 7月, 2016 1 次提交
    • M
      spi: Split bus and I/O locking · ef4d96ec
      Mark Brown 提交于
      The current SPI code attempts to use bus_lock_mutex for two purposes. One
      is to implement spi_bus_lock() which grants exclusive access to the bus.
      The other is to serialize access to the physical hardware. This duplicate
      purpose causes confusion which leads to cases where access is not locked
      when a caller holds the bus lock mutex. Fix this by splitting out the I/O
      functionality into a new io_mutex.
      
      This means taking both mutexes in the DMA path, replacing the existing
      mutex with the new I/O one in the message pump (the mutex now always
      being taken in the message pump) and taking the bus lock mutex in
      spi_sync(), allowing __spi_sync() to have no mutex handling.
      
      While we're at it hoist the mutex further up the message pump before we
      power up the device so that all power up/down of the block is covered by
      it and there are no races with in-line pumping of messages.
      Reported-by: NRich Felker <dalias@libc.org>
      Tested-by: NRich Felker <dalias@libc.org>
      Signed-off-by: NMark Brown <broonie@kernel.org>
      ef4d96ec