]> Git Repo - linux.git/commitdiff
Merge tag 'spi-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
authorLinus Torvalds <[email protected]>
Wed, 13 Mar 2024 18:07:37 +0000 (11:07 -0700)
committerLinus Torvalds <[email protected]>
Wed, 13 Mar 2024 18:07:37 +0000 (11:07 -0700)
Pull spi updates from Mark Brown:
 "This release sees some exciting changes from David Lechner which
  implements some optimisations that have been talked about for a long
  time which allows client drivers to pre-prepare SPI messages for
  repeated or low latency use. This lets us move work out of latency
  sensitive paths and avoid repeating work for frequently performed
  operations. As well as being useful in itself this will also be used
  in future to allow controllers to directly trigger SPI operations (eg,
  from interrupts).

  Otherwise this release has mostly been focused on cleanups, plus a
  couple of new devices:

   - Support for pre-optimising messages

   - A big set of updates from Uwe Kleine-König moving drivers to use
     APIs with more modern terminology for controllers

   - Major overhaul of the s3c64xx driver

   - Support for Google GS101 and Samsung Exynos850"

* tag 'spi-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (122 commits)
  spi: Introduce SPI_INVALID_CS and is_valid_cs()
  spi: Fix types of the last chip select storage variables
  spi: Consistently use BIT for cs_index_mask
  spi: Exctract spi_dev_check_cs() helper
  spi: Exctract spi_set_all_cs_unused() helper
  spi: s3c64xx: switch exynos850 to new port config data
  spi: s3c64xx: switch gs101 to new port config data
  spi: s3c64xx: deprecate fifo_lvl_mask, rx_lvl_offset and port_id
  spi: s3c64xx: get rid of the OF alias ID dependency
  spi: s3c64xx: introduce s3c64xx_spi_set_port_id()
  spi: s3c64xx: let the SPI core determine the bus number
  spi: s3c64xx: allow FIFO depth to be determined from the compatible
  spi: s3c64xx: retrieve the FIFO depth from the device tree
  spi: s3c64xx: determine the fifo depth only once
  spi: s3c64xx: allow full FIFO masks
  spi: s3c64xx: define a magic value
  spi: dt-bindings: introduce FIFO depth properties
  spi: axi-spi-engine: use struct_size() macro
  spi: axi-spi-engine: use __counted_by() attribute
  spi: axi-spi-engine: remove p from struct spi_engine_message_state
  ...

1  2 
Documentation/driver-api/driver-model/devres.rst
drivers/mmc/host/mmc_spi.c
drivers/net/ieee802154/ca8210.c
drivers/spi/spi-cadence-quadspi.c
drivers/spi/spi-cs42l43.c
drivers/spi/spi-ppc4xx.c

index e4df72c408d274eee6bea5da6e1e81d220dcfba8,49c6fd82cd5d956b1c666a412df7bf2710c92aa6..7be8b8dd5f00ad0a0dd816fc2d9fcaeff3278064
@@@ -420,7 -420,6 +420,7 @@@ POWE
    devm_reboot_mode_unregister()
  
  PWM
 +  devm_pwmchip_alloc()
    devm_pwmchip_add()
    devm_pwm_get()
    devm_fwnode_pwm_get()
@@@ -463,7 -462,7 +463,7 @@@ SLAVE DMA ENGIN
  SPI
    devm_spi_alloc_master()
    devm_spi_alloc_slave()
-   devm_spi_register_master()
+   devm_spi_register_controller()
  
  WATCHDOG
    devm_watchdog_register_device()
index 922275de0593f423f1ca6a693975f02b3c010cbc,bf35761f783af35271aa7d1915fffa3c6c1d9d20..09d7a6a0dc1aab68dfba5cc836e71e493b6e36c3
@@@ -15,6 -15,7 +15,6 @@@
  #include <linux/slab.h>
  #include <linux/module.h>
  #include <linux/bio.h>
 -#include <linux/dma-direction.h>
  #include <linux/crc7.h>
  #include <linux/crc-itu-t.h>
  #include <linux/scatterlist.h>
@@@ -509,7 -510,10 +509,7 @@@ mmc_spi_command_send(struct mmc_spi_hos
   * so we explicitly initialize it to all ones on RX paths.
   */
  static void
 -mmc_spi_setup_data_message(
 -      struct mmc_spi_host     *host,
 -      bool                    multiple,
 -      enum dma_data_direction direction)
 +mmc_spi_setup_data_message(struct mmc_spi_host *host, bool multiple, bool write)
  {
        struct spi_transfer     *t;
        struct scratch          *scratch = host->data;
        /* for reads, readblock() skips 0xff bytes before finding
         * the token; for writes, this transfer issues that token.
         */
 -      if (direction == DMA_TO_DEVICE) {
 +      if (write) {
                t = &host->token;
                memset(t, 0, sizeof(*t));
                t->len = 1;
        t = &host->crc;
        memset(t, 0, sizeof(*t));
        t->len = 2;
 -      if (direction == DMA_TO_DEVICE) {
 +      if (write) {
                /* the actual CRC may get written later */
                t->tx_buf = &scratch->crc_val;
        } else {
         * the next token (next data block, or STOP_TRAN).  We can try to
         * minimize I/O ops by using a single read to collect end-of-busy.
         */
 -      if (multiple || direction == DMA_TO_DEVICE) {
 +      if (multiple || write) {
                t = &host->early_status;
                memset(t, 0, sizeof(*t));
 -              t->len = (direction == DMA_TO_DEVICE) ? sizeof(scratch->status) : 1;
 +              t->len = write ? sizeof(scratch->status) : 1;
                t->tx_buf = host->ones;
                t->rx_buf = scratch->status;
                t->cs_change = 1;
@@@ -773,15 -777,15 +773,15 @@@ mmc_spi_data_do(struct mmc_spi_host *ho
  {
        struct spi_device       *spi = host->spi;
        struct spi_transfer     *t;
 -      enum dma_data_direction direction = mmc_get_dma_dir(data);
        struct scatterlist      *sg;
        unsigned                n_sg;
        bool                    multiple = (data->blocks > 1);
 -      const char              *write_or_read = (direction == DMA_TO_DEVICE) ? "write" : "read";
 +      bool                    write = (data->flags & MMC_DATA_WRITE);
 +      const char              *write_or_read = write ? "write" : "read";
        u32                     clock_rate;
        unsigned long           timeout;
  
 -      mmc_spi_setup_data_message(host, multiple, direction);
 +      mmc_spi_setup_data_message(host, multiple, write);
        t = &host->t;
  
        if (t->speed_hz)
  
                /* allow pio too; we don't allow highmem */
                kmap_addr = kmap(sg_page(sg));
 -              if (direction == DMA_TO_DEVICE)
 +              if (write)
                        t->tx_buf = kmap_addr + sg->offset;
                else
                        t->rx_buf = kmap_addr + sg->offset;
  
                        dev_dbg(&spi->dev, "    %s block, %d bytes\n", write_or_read, t->len);
  
 -                      if (direction == DMA_TO_DEVICE)
 +                      if (write)
                                status = mmc_spi_writeblock(host, t, timeout);
                        else
                                status = mmc_spi_readblock(host, t, timeout);
                }
  
                /* discard mappings */
 -              if (direction == DMA_FROM_DEVICE)
 +              if (write)
 +                      /* nothing to do */;
 +              else
                        flush_dcache_page(sg_page(sg));
                kunmap(sg_page(sg));
  
         * that can affect the STOP_TRAN logic.   Complete (and current)
         * MMC specs should sort that out before Linux starts using CMD23.
         */
 -      if (direction == DMA_TO_DEVICE && multiple) {
 +      if (write && multiple) {
                struct scratch  *scratch = host->data;
                int             tmp;
                const unsigned  statlen = sizeof(scratch->status);
@@@ -933,7 -935,7 +933,7 @@@ static void mmc_spi_request(struct mmc_
  #endif
  
        /* request exclusive bus access */
-       spi_bus_lock(host->spi->master);
+       spi_bus_lock(host->spi->controller);
  
  crc_recover:
        /* issue command; then optionally data and stop */
        }
  
        /* release the bus */
-       spi_bus_unlock(host->spi->master);
+       spi_bus_unlock(host->spi->controller);
  
        mmc_request_done(host->mmc, mrq);
  }
@@@ -1155,7 -1157,7 +1155,7 @@@ static int mmc_spi_probe(struct spi_dev
        /* We rely on full duplex transfers, mostly to reduce
         * per-transfer overheads (by making fewer transfers).
         */
-       if (spi->master->flags & SPI_CONTROLLER_HALF_DUPLEX)
+       if (spi->controller->flags & SPI_CONTROLLER_HALF_DUPLEX)
                return -EINVAL;
  
        /* MMC and SD specs only seem to care that sampling is on the
index f102f26cb0e349dbc4e103883e2a15a3cbfbdf58,f732c150462be2230b90c85d2c1515385f994e18..e685a7f946f0f8c8c217d88d193a0fbdd641ce96
@@@ -2857,13 -2857,19 +2857,13 @@@ static int ca8210_interrupt_init(struc
   */
  static int ca8210_dev_com_init(struct ca8210_priv *priv)
  {
 -      priv->mlme_workqueue = alloc_ordered_workqueue(
 -              "MLME work queue",
 -              WQ_UNBOUND
 -      );
 +      priv->mlme_workqueue = alloc_ordered_workqueue("MLME work queue", 0);
        if (!priv->mlme_workqueue) {
                dev_crit(&priv->spi->dev, "alloc of mlme_workqueue failed!\n");
                return -ENOMEM;
        }
  
 -      priv->irq_workqueue = alloc_ordered_workqueue(
 -              "ca8210 irq worker",
 -              WQ_UNBOUND
 -      );
 +      priv->irq_workqueue = alloc_ordered_workqueue("ca8210 irq worker", 0);
        if (!priv->irq_workqueue) {
                dev_crit(&priv->spi->dev, "alloc of irq_workqueue failed!\n");
                destroy_workqueue(priv->mlme_workqueue);
@@@ -2950,7 -2956,7 +2950,7 @@@ static int ca8210_test_interface_init(s
                node_name,
                sizeof(node_name),
                "ca8210@%d_%d",
-               priv->spi->master->bus_num,
+               priv->spi->controller->bus_num,
                spi_get_chipselect(priv->spi, 0)
        );
  
index 1a8d03958dffbfb77a4cd183d8a18fbd3ed53d63,0df732b03a2d88034d82461862dfecb2b8e71ab0..350b3dab3a05d148198568a780ed9505916687f9
@@@ -31,7 -31,9 +31,9 @@@
  #include <linux/timer.h>
  
  #define CQSPI_NAME                    "cadence-qspi"
- #define CQSPI_MAX_CHIPSELECT          16
+ #define CQSPI_MAX_CHIPSELECT          4
+ static_assert(CQSPI_MAX_CHIPSELECT <= SPI_CS_CNT_MAX);
  
  /* Quirks */
  #define CQSPI_NEEDS_WR_DELAY          BIT(0)
@@@ -1410,7 -1412,7 +1412,7 @@@ static int cqspi_mem_process(struct spi
  static int cqspi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
  {
        int ret;
-       struct cqspi_st *cqspi = spi_master_get_devdata(mem->spi->master);
+       struct cqspi_st *cqspi = spi_controller_get_devdata(mem->spi->controller);
        struct device *dev = &cqspi->pdev->dev;
  
        ret = pm_runtime_resume_and_get(dev);
@@@ -1619,6 -1621,7 +1621,7 @@@ static const struct spi_controller_mem_
  
  static int cqspi_setup_flash(struct cqspi_st *cqspi)
  {
+       unsigned int max_cs = cqspi->num_chipselect - 1;
        struct platform_device *pdev = cqspi->pdev;
        struct device *dev = &pdev->dev;
        struct device_node *np = dev->of_node;
                        return ret;
                }
  
-               if (cs >= CQSPI_MAX_CHIPSELECT) {
+               if (cs >= cqspi->num_chipselect) {
                        dev_err(dev, "Chip select %d out of range.\n", cs);
                        of_node_put(np);
                        return -EINVAL;
+               } else if (cs < max_cs) {
+                       max_cs = cs;
                }
  
                f_pdata = &cqspi->f_pdata[cs];
                }
        }
  
+       cqspi->num_chipselect = max_cs + 1;
        return 0;
  }
  
@@@ -1712,10 -1718,9 +1718,9 @@@ static int cqspi_probe(struct platform_
        int irq;
  
        host = devm_spi_alloc_host(&pdev->dev, sizeof(*cqspi));
-       if (!host) {
-               dev_err(&pdev->dev, "devm_spi_alloc_host failed\n");
+       if (!host)
                return -ENOMEM;
-       }
        host->mode_bits = SPI_RX_QUAD | SPI_RX_DUAL;
        host->mem_ops = &cqspi_mem_ops;
        host->mem_caps = &cqspi_mem_caps;
        cqspi->current_cs = -1;
        cqspi->sclk = 0;
  
-       host->num_chipselect = cqspi->num_chipselect;
        ret = cqspi_setup_flash(cqspi);
        if (ret) {
                dev_err(dev, "failed to setup flash parameters %d\n", ret);
                goto probe_setup_failed;
        }
  
+       host->num_chipselect = cqspi->num_chipselect;
        if (cqspi->use_direct_mode) {
                ret = cqspi_request_mmap_dma(cqspi);
                if (ret == -EPROBE_DEFER)
@@@ -1927,18 -1932,24 +1932,18 @@@ static void cqspi_remove(struct platfor
        pm_runtime_disable(&pdev->dev);
  }
  
 -static int cqspi_suspend(struct device *dev)
 +static int cqspi_runtime_suspend(struct device *dev)
  {
        struct cqspi_st *cqspi = dev_get_drvdata(dev);
 -      struct spi_controller *host = dev_get_drvdata(dev);
 -      int ret;
  
 -      ret = spi_controller_suspend(host);
        cqspi_controller_enable(cqspi, 0);
 -
        clk_disable_unprepare(cqspi->clk);
 -
 -      return ret;
 +      return 0;
  }
  
 -static int cqspi_resume(struct device *dev)
 +static int cqspi_runtime_resume(struct device *dev)
  {
        struct cqspi_st *cqspi = dev_get_drvdata(dev);
 -      struct spi_controller *host = dev_get_drvdata(dev);
  
        clk_prepare_enable(cqspi->clk);
        cqspi_wait_idle(cqspi);
  
        cqspi->current_cs = -1;
        cqspi->sclk = 0;
 +      return 0;
 +}
 +
 +static int cqspi_suspend(struct device *dev)
 +{
 +      struct cqspi_st *cqspi = dev_get_drvdata(dev);
 +
 +      return spi_controller_suspend(cqspi->host);
 +}
  
 -      return spi_controller_resume(host);
 +static int cqspi_resume(struct device *dev)
 +{
 +      struct cqspi_st *cqspi = dev_get_drvdata(dev);
 +
 +      return spi_controller_resume(cqspi->host);
  }
  
 -static DEFINE_RUNTIME_DEV_PM_OPS(cqspi_dev_pm_ops, cqspi_suspend,
 -                               cqspi_resume, NULL);
 +static const struct dev_pm_ops cqspi_dev_pm_ops = {
 +      RUNTIME_PM_OPS(cqspi_runtime_suspend, cqspi_runtime_resume, NULL)
 +      SYSTEM_SLEEP_PM_OPS(cqspi_suspend, cqspi_resume)
 +};
  
  static const struct cqspi_driver_platdata cdns_qspi = {
        .quirks = CQSPI_DISABLE_DAC_MODE,
index adf19e8c4c8a0d1ef9ede14374e8ab6638073a82,d45d9e2e1611623e3b516e91f55e3b0150d21276..27c995b657f2c66b58efcf8a24103e419c9cb71f
@@@ -148,7 -148,8 +148,7 @@@ static void cs42l43_set_cs(struct spi_d
  {
        struct cs42l43_spi *priv = spi_controller_get_devdata(spi->controller);
  
 -      if (spi_get_chipselect(spi, 0) == 0)
 -              regmap_write(priv->regmap, CS42L43_SPI_CONFIG2, !is_high);
 +      regmap_write(priv->regmap, CS42L43_SPI_CONFIG2, !is_high);
  }
  
  static int cs42l43_prepare_message(struct spi_controller *ctlr, struct spi_message *msg)
@@@ -201,6 -202,11 +201,11 @@@ static size_t cs42l43_spi_max_length(st
        return CS42L43_SPI_MAX_LENGTH;
  }
  
+ static void cs42l43_release_of_node(void *data)
+ {
+       fwnode_handle_put(data);
+ }
  static int cs42l43_spi_probe(struct platform_device *pdev)
  {
        struct cs42l43 *cs42l43 = dev_get_drvdata(pdev->dev.parent);
        priv->ctlr->transfer_one = cs42l43_transfer_one;
        priv->ctlr->set_cs = cs42l43_set_cs;
        priv->ctlr->max_transfer_size = cs42l43_spi_max_length;
-       if (is_of_node(fwnode))
-               fwnode = fwnode_get_named_child_node(fwnode, "spi");
-       device_set_node(&priv->ctlr->dev, fwnode);
        priv->ctlr->mode_bits = SPI_3WIRE | SPI_MODE_X_MASK;
        priv->ctlr->flags = SPI_CONTROLLER_HALF_DUPLEX;
        priv->ctlr->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16) |
        regmap_write(priv->regmap, CS42L43_SPI_CONFIG3, 0);
        regmap_write(priv->regmap, CS42L43_SPI_CONFIG4, CS42L43_SPI_STALL_ENA_MASK);
  
+       if (is_of_node(fwnode)) {
+               fwnode = fwnode_get_named_child_node(fwnode, "spi");
+               ret = devm_add_action(priv->dev, cs42l43_release_of_node, fwnode);
+               if (ret) {
+                       fwnode_handle_put(fwnode);
+                       return ret;
+               }
+       }
+       device_set_node(&priv->ctlr->dev, fwnode);
        ret = devm_spi_register_controller(priv->dev, priv->ctlr);
        if (ret) {
                dev_err(priv->dev, "Failed to register SPI controller: %d\n", ret);
diff --combined drivers/spi/spi-ppc4xx.c
index 82d6264841fc7f090a5541235569e40023330483,b07bb5e5811ec82bf75ec59d64b99d89e0105874..942c3117ab3a904de67c59e7e13e5d40995dd00a
  #include <linux/slab.h>
  #include <linux/errno.h>
  #include <linux/wait.h>
 +#include <linux/platform_device.h>
  #include <linux/of_address.h>
  #include <linux/of_irq.h>
  #include <linux/of_platform.h>
  #include <linux/interrupt.h>
  #include <linux/delay.h>
 +#include <linux/platform_device.h>
  
  #include <linux/spi/spi.h>
  #include <linux/spi/spi_bitbang.h>
@@@ -168,8 -166,10 +168,8 @@@ static int spi_ppc4xx_setupxfer(struct 
        int scr;
        u8 cdm = 0;
        u32 speed;
 -      u8 bits_per_word;
  
        /* Start with the generic configuration for this device. */
 -      bits_per_word = spi->bits_per_word;
        speed = spi->max_speed_hz;
  
        /*
         * the transfer to overwrite the generic configuration with zeros.
         */
        if (t) {
 -              if (t->bits_per_word)
 -                      bits_per_word = t->bits_per_word;
 -
                if (t->speed_hz)
                        speed = min(t->speed_hz, spi->max_speed_hz);
        }
@@@ -359,22 -362,22 +359,22 @@@ static int spi_ppc4xx_of_probe(struct p
  
        /* Setup the state for the bitbang driver */
        bbp = &hw->bitbang;
-       bbp->master = hw->host;
+       bbp->ctlr = hw->host;
        bbp->setup_transfer = spi_ppc4xx_setupxfer;
        bbp->txrx_bufs = spi_ppc4xx_txrx;
        bbp->use_dma = 0;
-       bbp->master->setup = spi_ppc4xx_setup;
-       bbp->master->cleanup = spi_ppc4xx_cleanup;
-       bbp->master->bits_per_word_mask = SPI_BPW_MASK(8);
-       bbp->master->use_gpio_descriptors = true;
+       bbp->ctlr->setup = spi_ppc4xx_setup;
+       bbp->ctlr->cleanup = spi_ppc4xx_cleanup;
+       bbp->ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
+       bbp->ctlr->use_gpio_descriptors = true;
        /*
         * The SPI core will count the number of GPIO descriptors to figure
         * out the number of chip selects available on the platform.
         */
-       bbp->master->num_chipselect = 0;
+       bbp->ctlr->num_chipselect = 0;
  
        /* the spi->mode bits understood by this driver: */
-       bbp->master->mode_bits =
+       bbp->ctlr->mode_bits =
                SPI_CPHA | SPI_CPOL | SPI_CS_HIGH | SPI_LSB_FIRST;
  
        /* Get the clock for the OPB */
This page took 0.127485 seconds and 4 git commands to generate.