diff options
author | Mark Brown <broonie@kernel.org> | 2018-08-10 17:51:50 +0100 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2018-08-10 17:51:50 +0100 |
commit | c3c7126248a0750790ee33c4bd80a1847f55f5b6 (patch) | |
tree | 896d70ea0d5e7dd5859f7577f9d16fd12f8a16e0 /drivers/spi | |
parent | 1ffaddd029c867d134a1dde39f540dcc8c52e274 (diff) | |
parent | 563a53f3906a6b43692498e5b3ae891fac93a4af (diff) | |
download | linux-stable-c3c7126248a0750790ee33c4bd80a1847f55f5b6.tar.gz linux-stable-c3c7126248a0750790ee33c4bd80a1847f55f5b6.tar.bz2 linux-stable-c3c7126248a0750790ee33c4bd80a1847f55f5b6.zip |
Merge branch 'spi-4.18' into spi-linus
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/spi-cadence.c | 4 | ||||
-rw-r--r-- | drivers/spi/spi-davinci.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi-dw.c | 3 | ||||
-rw-r--r-- | drivers/spi/spi-fsl-dspi.c | 12 | ||||
-rw-r--r-- | drivers/spi/spi-orion.c | 77 | ||||
-rw-r--r-- | drivers/spi/spi-sh-msiof.c | 53 |
6 files changed, 86 insertions, 65 deletions
diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c index f3dad6fcdc35..7c88f74f7f47 100644 --- a/drivers/spi/spi-cadence.c +++ b/drivers/spi/spi-cadence.c @@ -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; diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 577084bb911b..a02099c90c5c 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -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; /* diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index f693bfe95ab9..a087464efdd7 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -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"); diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 0630962ce442..1c1070114246 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -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) diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index d01a6adc726e..47ef6b1a2e76 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c @@ -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: diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 0e74cbf9929d..539d6d1a277a 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c @@ -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)) { |