Merge branch 'spi-4.18' into spi-linus
authorMark Brown <broonie@kernel.org>
Fri, 10 Aug 2018 16:51:50 +0000 (17:51 +0100)
committerMark Brown <broonie@kernel.org>
Fri, 10 Aug 2018 16:51:50 +0000 (17:51 +0100)
drivers/spi/spi-cadence.c
drivers/spi/spi-davinci.c
drivers/spi/spi-dw.c
drivers/spi/spi-fsl-dspi.c
drivers/spi/spi-orion.c
drivers/spi/spi-sh-msiof.c

index f3dad6f..7c88f74 100644 (file)
@@ -319,7 +319,7 @@ static void cdns_spi_fill_tx_fifo(struct cdns_spi *xspi)
                 */
                if (cdns_spi_read(xspi, CDNS_SPI_ISR) &
                    CDNS_SPI_IXR_TXFULL)
-                       usleep_range(10, 20);
+                       udelay(10);
 
                if (xspi->txbuf)
                        cdns_spi_write(xspi, CDNS_SPI_TXD, *xspi->txbuf++);
@@ -739,7 +739,7 @@ static int __maybe_unused cnds_runtime_resume(struct device *dev)
        ret = clk_prepare_enable(xspi->ref_clk);
        if (ret) {
                dev_err(dev, "Cannot enable device clock.\n");
-               clk_disable(xspi->pclk);
+               clk_disable_unprepare(xspi->pclk);
                return ret;
        }
        return 0;
index 577084b..a02099c 100644 (file)
@@ -217,7 +217,7 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value)
        pdata = &dspi->pdata;
 
        /* program delay transfers if tx_delay is non zero */
-       if (spicfg->wdelay)
+       if (spicfg && spicfg->wdelay)
                spidat1 |= SPIDAT1_WDEL;
 
        /*
index f693bfe..a087464 100644 (file)
@@ -485,6 +485,8 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
        dws->dma_inited = 0;
        dws->dma_addr = (dma_addr_t)(dws->paddr + DW_SPI_DR);
 
+       spi_controller_set_devdata(master, dws);
+
        ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, dev_name(dev),
                          master);
        if (ret < 0) {
@@ -518,7 +520,6 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
                }
        }
 
-       spi_controller_set_devdata(master, dws);
        ret = devm_spi_register_controller(dev, master);
        if (ret) {
                dev_err(&master->dev, "problem registering spi master\n");
index 0630962..1c10701 100644 (file)
@@ -943,11 +943,23 @@ static int dspi_resume(struct device *dev)
 
 static SIMPLE_DEV_PM_OPS(dspi_pm, dspi_suspend, dspi_resume);
 
+static const struct regmap_range dspi_volatile_ranges[] = {
+       regmap_reg_range(SPI_MCR, SPI_TCR),
+       regmap_reg_range(SPI_SR, SPI_SR),
+       regmap_reg_range(SPI_PUSHR, SPI_RXFR3),
+};
+
+static const struct regmap_access_table dspi_volatile_table = {
+       .yes_ranges     = dspi_volatile_ranges,
+       .n_yes_ranges   = ARRAY_SIZE(dspi_volatile_ranges),
+};
+
 static const struct regmap_config dspi_regmap_config = {
        .reg_bits = 32,
        .val_bits = 32,
        .reg_stride = 4,
        .max_register = 0x88,
+       .volatile_table = &dspi_volatile_table,
 };
 
 static void dspi_init(struct fsl_dspi *dspi)
index d01a6ad..47ef6b1 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
+#include <linux/of_gpio.h>
 #include <linux/clk.h>
 #include <linux/sizes.h>
 #include <linux/gpio.h>
@@ -681,9 +682,9 @@ static int orion_spi_probe(struct platform_device *pdev)
                goto out_rel_axi_clk;
        }
 
-       /* Scan all SPI devices of this controller for direct mapped devices */
        for_each_available_child_of_node(pdev->dev.of_node, np) {
                u32 cs;
+               int cs_gpio;
 
                /* Get chip-select number from the "reg" property */
                status = of_property_read_u32(np, "reg", &cs);
@@ -695,6 +696,44 @@ static int orion_spi_probe(struct platform_device *pdev)
                }
 
                /*
+                * Initialize the CS GPIO:
+                * - properly request the actual GPIO signal
+                * - de-assert the logical signal so that all GPIO CS lines
+                *   are inactive when probing for slaves
+                * - find an unused physical CS which will be driven for any
+                *   slave which uses a CS GPIO
+                */
+               cs_gpio = of_get_named_gpio(pdev->dev.of_node, "cs-gpios", cs);
+               if (cs_gpio > 0) {
+                       char *gpio_name;
+                       int cs_flags;
+
+                       if (spi->unused_hw_gpio == -1) {
+                               dev_info(&pdev->dev,
+                                       "Selected unused HW CS#%d for any GPIO CSes\n",
+                                       cs);
+                               spi->unused_hw_gpio = cs;
+                       }
+
+                       gpio_name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+                                       "%s-CS%d", dev_name(&pdev->dev), cs);
+                       if (!gpio_name) {
+                               status = -ENOMEM;
+                               goto out_rel_axi_clk;
+                       }
+
+                       cs_flags = of_property_read_bool(np, "spi-cs-high") ?
+                               GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH;
+                       status = devm_gpio_request_one(&pdev->dev, cs_gpio,
+                                       cs_flags, gpio_name);
+                       if (status) {
+                               dev_err(&pdev->dev,
+                                       "Can't request GPIO for CS %d\n", cs);
+                               goto out_rel_axi_clk;
+                       }
+               }
+
+               /*
                 * Check if an address is configured for this SPI device. If
                 * not, the MBus mapping via the 'ranges' property in the 'soc'
                 * node is not configured and this device should not use the
@@ -740,44 +779,8 @@ static int orion_spi_probe(struct platform_device *pdev)
        if (status < 0)
                goto out_rel_pm;
 
-       if (master->cs_gpios) {
-               int i;
-               for (i = 0; i < master->num_chipselect; ++i) {
-                       char *gpio_name;
-
-                       if (!gpio_is_valid(master->cs_gpios[i])) {
-                               continue;
-                       }
-
-                       gpio_name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
-                                       "%s-CS%d", dev_name(&pdev->dev), i);
-                       if (!gpio_name) {
-                               status = -ENOMEM;
-                               goto out_rel_master;
-                       }
-
-                       status = devm_gpio_request(&pdev->dev,
-                                       master->cs_gpios[i], gpio_name);
-                       if (status) {
-                               dev_err(&pdev->dev,
-                                       "Can't request GPIO for CS %d\n",
-                                       master->cs_gpios[i]);
-                               goto out_rel_master;
-                       }
-                       if (spi->unused_hw_gpio == -1) {
-                               dev_info(&pdev->dev,
-                                       "Selected unused HW CS#%d for any GPIO CSes\n",
-                                       i);
-                               spi->unused_hw_gpio = i;
-                       }
-               }
-       }
-
-
        return status;
 
-out_rel_master:
-       spi_unregister_master(master);
 out_rel_pm:
        pm_runtime_disable(&pdev->dev);
 out_rel_axi_clk:
index 0e74cbf..539d6d1 100644 (file)
@@ -49,6 +49,7 @@ struct sh_msiof_spi_priv {
        struct platform_device *pdev;
        struct sh_msiof_spi_info *info;
        struct completion done;
+       struct completion done_txdma;
        unsigned int tx_fifo_size;
        unsigned int rx_fifo_size;
        unsigned int min_div_pow;
@@ -649,19 +650,21 @@ static int sh_msiof_slave_abort(struct spi_master *master)
 
        p->slave_aborted = true;
        complete(&p->done);
+       complete(&p->done_txdma);
        return 0;
 }
 
-static int sh_msiof_wait_for_completion(struct sh_msiof_spi_priv *p)
+static int sh_msiof_wait_for_completion(struct sh_msiof_spi_priv *p,
+                                       struct completion *x)
 {
        if (spi_controller_is_slave(p->master)) {
-               if (wait_for_completion_interruptible(&p->done) ||
+               if (wait_for_completion_interruptible(x) ||
                    p->slave_aborted) {
                        dev_dbg(&p->pdev->dev, "interrupted\n");
                        return -EINTR;
                }
        } else {
-               if (!wait_for_completion_timeout(&p->done, HZ)) {
+               if (!wait_for_completion_timeout(x, HZ)) {
                        dev_err(&p->pdev->dev, "timeout\n");
                        return -ETIMEDOUT;
                }
@@ -711,7 +714,7 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
        }
 
        /* wait for tx fifo to be emptied / rx fifo to be filled */
-       ret = sh_msiof_wait_for_completion(p);
+       ret = sh_msiof_wait_for_completion(p, &p->done);
        if (ret)
                goto stop_reset;
 
@@ -740,10 +743,7 @@ stop_ier:
 
 static void sh_msiof_dma_complete(void *arg)
 {
-       struct sh_msiof_spi_priv *p = arg;
-
-       sh_msiof_write(p, IER, 0);
-       complete(&p->done);
+       complete(arg);
 }
 
 static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
@@ -764,7 +764,7 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
                        return -EAGAIN;
 
                desc_rx->callback = sh_msiof_dma_complete;
-               desc_rx->callback_param = p;
+               desc_rx->callback_param = &p->done;
                cookie = dmaengine_submit(desc_rx);
                if (dma_submit_error(cookie))
                        return cookie;
@@ -782,13 +782,8 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
                        goto no_dma_tx;
                }
 
-               if (rx) {
-                       /* No callback */
-                       desc_tx->callback = NULL;
-               } else {
-                       desc_tx->callback = sh_msiof_dma_complete;
-                       desc_tx->callback_param = p;
-               }
+               desc_tx->callback = sh_msiof_dma_complete;
+               desc_tx->callback_param = &p->done_txdma;
                cookie = dmaengine_submit(desc_tx);
                if (dma_submit_error(cookie)) {
                        ret = cookie;
@@ -805,6 +800,8 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
        sh_msiof_write(p, IER, ier_bits);
 
        reinit_completion(&p->done);
+       if (tx)
+               reinit_completion(&p->done_txdma);
        p->slave_aborted = false;
 
        /* Now start DMA */
@@ -819,17 +816,24 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
                goto stop_dma;
        }
 
-       /* wait for tx/rx DMA completion */
-       ret = sh_msiof_wait_for_completion(p);
-       if (ret)
-               goto stop_reset;
+       if (tx) {
+               /* wait for tx DMA completion */
+               ret = sh_msiof_wait_for_completion(p, &p->done_txdma);
+               if (ret)
+                       goto stop_reset;
+       }
 
-       if (!rx) {
-               reinit_completion(&p->done);
-               sh_msiof_write(p, IER, IER_TEOFE);
+       if (rx) {
+               /* wait for rx DMA completion */
+               ret = sh_msiof_wait_for_completion(p, &p->done);
+               if (ret)
+                       goto stop_reset;
 
+               sh_msiof_write(p, IER, 0);
+       } else {
                /* wait for tx fifo to be emptied */
-               ret = sh_msiof_wait_for_completion(p);
+               sh_msiof_write(p, IER, IER_TEOFE);
+               ret = sh_msiof_wait_for_completion(p, &p->done);
                if (ret)
                        goto stop_reset;
        }
@@ -1327,6 +1331,7 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
        p->min_div_pow = chipdata->min_div_pow;
 
        init_completion(&p->done);
+       init_completion(&p->done_txdma);
 
        p->clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(p->clk)) {