1. 09 Dec, 2020 2 commits
    • Damien Le Moal's avatar
      spi: dw: Add support for 32-bits max xfer size · a51acc24
      Damien Le Moal authored
      The Synopsis DesignWare DW_apb_ssi specifications version 3.23 onward
      define a 32-bits maximum transfer size synthesis parameter
      (SSI_MAX_XFER_SIZE=32) in addition to the legacy 16-bits configuration
      (SSI_MAX_XFER_SIZE=16) for SPI controllers. When SSI_MAX_XFER_SIZE=32,
      the layout of the ctrlr0 register changes, moving the data frame format
      field from bits [3..0] to bits [16..20], and the RX/TX FIFO word size
      can be up to 32-bits.
      
      To support this new format, introduce the DW SPI capability flag
      DW_SPI_CAP_DFS32 to indicate that a controller is configured with
      SSI_MAX_XFER_SIZE=32. Since SSI_MAX_XFER_SIZE is a controller synthesis
      parameter not accessible through a register, the detection of this
      parameter value is done in spi_hw_init() by writing and reading the
      ctrlr0 register and testing the value of bits [3..0]. These bits are
      ignored (unchanged) for SSI_MAX_XFER_SIZE=16, allowing the detection.
      If a DFS32 capable SPI controller is detected, the new field dfs_offset
      in struct dw_spi is set to SPI_DFS32_OFFSET (16).
      
      dw_spi_update_config() is modified to set the data frame size field at
      the correct position is the CTRLR0 register, as indicated by the
      dfs_offset field of the dw_spi structure.
      
      The DW_SPI_CAP_DFS32 flag is also unconditionally set for SPI slave
      controllers, e.g. controllers that have the DW_SPI_CAP_DWC_SSI
      capability flag set. However, for these ssi controllers, the dfs_offset
      field is set to 0 as before (as per specifications).
      
      Finally, for any controller with the DW_SPI_CAP_DFS32 capability flag
      set, dw_spi_add_host() extends the value of bits_per_word_mask from
      16-bits to 32-bits. dw_reader() and dw_writer() are also modified to
      handle 32-bits iTX/RX FIFO words.
      Suggested-by: default avatarSean Anderson <seanga2@gmail.com>
      Signed-off-by: default avatarDamien Le Moal <damien.lemoal@wdc.com>
      Acked-by: default avatarSerge Semin <fancer.lancer@gmail.com>
      Link: https://lore.kernel.org/r/20201206011817.11700-3-damien.lemoal@wdc.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      a51acc24
    • Damien Le Moal's avatar
      dt-bindings: spi: dw-apb-ssi: Add Canaan K210 SPI controller · 7b14a272
      Damien Le Moal authored
      Update the snps,dw-apb-ssi.yaml document to include the compatibility
      string "canaan,k210-spi" compatible string for the Canaan Kendryte K210
      RISC-V SoC DW apb_ssi V4 SPI controller.
      Signed-off-by: default avatarDamien Le Moal <damien.lemoal@wdc.com>
      Acked-by: default avatarSerge Semin <fancer.lancer@gmail.com>
      Link: https://lore.kernel.org/r/20201206011817.11700-2-damien.lemoal@wdc.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      7b14a272
  2. 08 Dec, 2020 1 commit
  3. 07 Dec, 2020 22 commits
  4. 04 Dec, 2020 1 commit
  5. 27 Nov, 2020 2 commits
  6. 25 Nov, 2020 2 commits
  7. 24 Nov, 2020 2 commits
  8. 23 Nov, 2020 2 commits
  9. 20 Nov, 2020 4 commits
    • Serge Semin's avatar
      spi: Take the SPI IO-mutex in the spi_setup() method · 4fae3a58
      Serge Semin authored
      I've discovered that due to the recent commit 49d7d695 ("spi: dw:
      Explicitly de-assert CS on SPI transfer completion") a concurrent usage of
      the spidev devices with different chip-selects causes the "SPI transfer
      timed out" error. The root cause of the problem has turned to be in a race
      condition of the SPI-transfer execution procedure and the spi_setup()
      method being called at the same time. In particular in calling the
      spi_set_cs(false) while there is an SPI-transfer being executed. In my
      case due to the commit cited above all CSs get to be switched off by
      calling the spi_setup() for /dev/spidev0.1 while there is an concurrent
      SPI-transfer execution performed on /dev/spidev0.0. Of course a situation
      of the spi_setup() being called while there is an SPI-transfer being
      executed for two different SPI peripheral devices of the same controller
      may happen not only for the spidev driver, but for instance for MMC SPI +
      some another device, or spi_setup() being called from an SPI-peripheral
      probe method while some other device has already been probed and is being
      used by a corresponding driver...
      
      Of course I could have provided a fix affecting the DW APB SSI driver
      only, for instance, by creating a mutual exclusive access to the set_cs
      callback and setting/clearing only the bit responsible for the
      corresponding chip-select. But after a short research I've discovered that
      the problem most likely affects a lot of the other drivers:
      - drivers/spi/spi-sun4i.c - RMW the chip-select register;
      - drivers/spi/spi-rockchip.c - RMW the chip-select register;
      - drivers/spi/spi-qup.c - RMW a generic force-CS flag in a CSR.
      - drivers/spi/spi-sifive.c - set a generic CS-mode flag in a CSR.
      - drivers/spi/spi-bcm63xx-hsspi.c - uses an internal mutex to serialize
        the bus config changes, but still isn't protected from the race
        condition described above;
      - drivers/spi/spi-geni-qcom.c - RMW a chip-select internal flag and set the
        CS state in HW;
      - drivers/spi/spi-orion.c - RMW a chip-select register;
      - drivers/spi/spi-cadence.c - RMW a chip-select register;
      - drivers/spi/spi-armada-3700.c - RMW a chip-select register;
      - drivers/spi/spi-lantiq-ssc.c - overwrites the chip-select register;
      - drivers/spi/spi-sun6i.c - RMW a chip-select register;
      - drivers/spi/spi-synquacer.c - RMW a chip-select register;
      - drivers/spi/spi-altera.c - directly sets the chip-select state;
      - drivers/spi/spi-omap2-mcspi.c - RMW an internally cached CS state and
        writes it to HW;
      - drivers/spi/spi-mt65xx.c - RMW some CSR;
      - drivers/spi/spi-jcore.c - directly sets the chip-selects state;
      - drivers/spi/spi-mt7621.c - RMW a chip-select register;
      
      I could have missed some drivers, but a scale of the problem is obvious.
      As you can see most of the drivers perform an unprotected
      Read-modify-write chip-select register modification in the set_cs callback.
      Seeing the spi_setup() function is calling the spi_set_cs() and it can be
      executed concurrently with SPI-transfers exec procedure, which also calls
      spi_set_cs() in the SPI core spi_transfer_one_message() method, the race
      condition of the register modification turns to be obvious.
      
      To sum up the problem denoted above affects each driver for a controller
      having more than one chip-select lane and which:
      1) performs the RMW to some CS-related register with no serialization;
      2) directly disables any CS on spi_set_cs(dev, false).
      * the later is the case of the DW APB SSI driver.
      
      The controllers which equipped with a single CS theoretically can also
      experience the problem, but in practice will not since normally the
      spi_setup() isn't called concurrently with the SPI-transfers executed on
      the same SPI peripheral device.
      
      In order to generically fix the denoted bug I'd suggest to serialize an
      access to the controller IO by taking the IO mutex in the spi_setup()
      callback. The mutex is held while there is an SPI communication going on
      on the SPI-bus of the corresponding SPI-controller. So calling the
      spi_setup() method and disabling/updating the CS state within it would be
      safe while there is no any SPI-transfers being executed. Also note I
      suppose it would be safer to protect the spi_controller->setup() callback
      invocation too, seeing some of the SPI-controller drivers update a HW
      state in there.
      
      Fixes: 49d7d695 ("spi: dw: Explicitly de-assert CS on SPI transfer completion")
      Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Link: https://lore.kernel.org/r/20201117094517.5654-1-Sergey.Semin@baikalelectronics.ruSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      4fae3a58
    • Uwe Kleine-König's avatar
      spi: Warn when a driver's remove callback returns an error · 7795d475
      Uwe Kleine-König authored
      The driver core ignores the return value of struct device_driver::remove
      (because in general there is nothing that can be done about that). So
      add a warning when an spi driver returns an error.
      
      This simplifies the quest to make struct device_driver::remove return void.
      A consequent change would be to make struct spi_driver::remove return void,
      but I'm keeping this quest for later (or someone else).
      Signed-off-by: default avatarUwe Kleine-König <u.kleine-koenig@pengutronix.de>
      Link: https://lore.kernel.org/r/20201119161604.2633521-3-u.kleine-koenig@pengutronix.deSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      7795d475
    • Uwe Kleine-König's avatar
      spi: Use bus_type functions for probe, remove and shutdown · 9db34ee6
      Uwe Kleine-König authored
      The eventual goal is to get rid of the callbacks in struct
      device_driver. Other than not using driver callbacks there should be no
      side effect of this patch.
      Signed-off-by: default avatarUwe Kleine-König <u.kleine-koenig@pengutronix.de>
      Link: https://lore.kernel.org/r/20201119161604.2633521-2-u.kleine-koenig@pengutronix.deSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      9db34ee6
    • Uwe Kleine-König's avatar
      spi: fix resource leak for drivers without .remove callback · 440408db
      Uwe Kleine-König authored
      Consider an spi driver with a .probe but without a .remove callback (e.g.
      rtc-ds1347). The function spi_drv_probe() is called to bind a device and
      so dev_pm_domain_attach() is called. As there is no remove callback
      spi_drv_remove() isn't called at unbind time however and so calling
      dev_pm_domain_detach() is missed and the pm domain keeps active.
      
      To fix this always use both spi_drv_probe() and spi_drv_remove() and
      make them handle the respective callback not being set. This has the
      side effect that for a (hypothetical) driver that has neither .probe nor
      remove the clk and pm domain setup is done.
      
      Fixes: 33cf00e5 ("spi: attach/detach SPI device to the ACPI power domain")
      Signed-off-by: default avatarUwe Kleine-König <u.kleine-koenig@pengutronix.de>
      Link: https://lore.kernel.org/r/20201119161604.2633521-1-u.kleine-koenig@pengutronix.deSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      440408db
  10. 18 Nov, 2020 1 commit
  11. 17 Nov, 2020 1 commit