diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-07 07:44:33 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-07 07:44:33 -0700 |
commit | 9bff9dfc513bd5de72cb59f4bffb72cf0a5aa526 (patch) | |
tree | 3229206f8aa93ca4d34585b7eb4d3ed272397ae2 /drivers/spi/spi.c | |
parent | Merge tag 'regulator-v5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator (diff) | |
parent | Merge branch 'spi-5.2' into spi-next (diff) | |
download | linux-dev-9bff9dfc513bd5de72cb59f4bffb72cf0a5aa526.tar.xz linux-dev-9bff9dfc513bd5de72cb59f4bffb72cf0a5aa526.zip |
Merge tag 'spi-v5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi updates from Mark Brown:
"One small feature was added this release but the bulk of the diffstat
and the changelog comes from the fact that several older drivers got
some fairly hefty reworks and a couple of new drivers were added:
- Support for detailed control of timing around chip selects from
Sowjanya Komatineni.
- A big set of fixes and imrovements for the Tegra114 driver from
Sowjanya Komatineni.
- A big simplification of the GPIO driver from Andrey Smirnov.
- DMA support and fixes for the Freescale LPSPI driver from Clark
Wang.
- Fixes and optimizations for the bcm2835aux from Martin Sparl.
- New drivers for Mediatek MT7621 (graduated from staging) and Zynq
QSPI"
[ This is a so-called "evil merge" that additionally removes a warning
due to an unused variable 'i' introduced by commit 1dfbf334f123 ("spi:
ep93xx: Convert to use CS GPIO descriptors") - Linus ]
* tag 'spi-v5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (127 commits)
spi: rspi: Fix handling of QSPI code when transmit and receive
spi: atmel-quadspi: fix crash while suspending
spi: stm32: return the get_irq error
spi: tegra114: fix PIO transfer
spi: pxa2xx: fix SCR (divisor) calculation
spi: Clear SPI_CS_HIGH flag from bad_bits for GPIO chip-select
spi: ep93xx: Convert to use CS GPIO descriptors
spi: AD ASoC: declare missing of table
spi: spi-mem: zynq-qspi: Fix build error on architectures missing readsl/writesl
spi: stm32-qspi: manage the get_irq error case
spi/spi-bcm2835: Split transfers that exceed DLEN
spi: expand mode support
dt-bindings: spi: spi-mt65xx: add support for MT8516
spi: pxa2xx: Add support for Intel Comet Lake
spi/trace: Cap buffer contents at 64 bytes
spi: Release spi_res after finalizing message
spi: Remove warning in spi_split_transfers_maxsize()
spi: Remove one needless transfer speed fall back case
spi: sh-msiof: Document r8a77470 bindings
spi: pxa2xx: use a module softdep for dw_dmac
...
Diffstat (limited to 'drivers/spi/spi.c')
-rw-r--r-- | drivers/spi/spi.c | 76 |
1 files changed, 48 insertions, 28 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 93986f879b09..5e75944ad5d1 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -36,6 +36,8 @@ #define CREATE_TRACE_POINTS #include <trace/events/spi.h> +EXPORT_TRACEPOINT_SYMBOL(spi_transfer_start); +EXPORT_TRACEPOINT_SYMBOL(spi_transfer_stop); #include "internals.h" @@ -1039,6 +1041,8 @@ static int spi_map_msg(struct spi_controller *ctlr, struct spi_message *msg) if (max_tx || max_rx) { list_for_each_entry(xfer, &msg->transfers, transfer_list) { + if (!xfer->len) + continue; if (!xfer->tx_buf) xfer->tx_buf = ctlr->dummy_tx; if (!xfer->rx_buf) @@ -1177,10 +1181,10 @@ out: if (msg->status && ctlr->handle_err) ctlr->handle_err(ctlr, msg); - spi_res_release(ctlr, msg); - spi_finalize_current_message(ctlr); + spi_res_release(ctlr, msg); + return ret; } @@ -2195,6 +2199,8 @@ static int spi_get_gpio_descs(struct spi_controller *ctlr) */ cs[i] = devm_gpiod_get_index_optional(dev, "cs", i, GPIOD_OUT_LOW); + if (IS_ERR(cs[i])) + return PTR_ERR(cs[i]); if (cs[i]) { /* @@ -2261,7 +2267,7 @@ int spi_register_controller(struct spi_controller *ctlr) { struct device *dev = ctlr->dev.parent; struct boardinfo *bi; - int status = -ENODEV; + int status; int id, first_dynamic; if (!dev) @@ -2275,24 +2281,6 @@ int spi_register_controller(struct spi_controller *ctlr) if (status) return status; - if (!spi_controller_is_slave(ctlr)) { - if (ctlr->use_gpio_descriptors) { - status = spi_get_gpio_descs(ctlr); - if (status) - return status; - /* - * A controller using GPIO descriptors always - * supports SPI_CS_HIGH if need be. - */ - ctlr->mode_bits |= SPI_CS_HIGH; - } else { - /* Legacy code path for GPIOs from DT */ - status = of_spi_register_master(ctlr); - if (status) - return status; - } - } - /* even if it's just one always-selected device, there must * be at least one chipselect */ @@ -2349,6 +2337,25 @@ int spi_register_controller(struct spi_controller *ctlr) * registration fails if the bus ID is in use. */ dev_set_name(&ctlr->dev, "spi%u", ctlr->bus_num); + + if (!spi_controller_is_slave(ctlr)) { + if (ctlr->use_gpio_descriptors) { + status = spi_get_gpio_descs(ctlr); + if (status) + return status; + /* + * A controller using GPIO descriptors always + * supports SPI_CS_HIGH if need be. + */ + ctlr->mode_bits |= SPI_CS_HIGH; + } else { + /* Legacy code path for GPIOs from DT */ + status = of_spi_register_master(ctlr); + if (status) + return status; + } + } + status = device_add(&ctlr->dev); if (status < 0) { /* free bus id */ @@ -2781,11 +2788,6 @@ static int __spi_split_transfer_maxsize(struct spi_controller *ctlr, size_t offset; size_t count, i; - /* warn once about this fact that we are splitting a transfer */ - dev_warn_once(&msg->spi->dev, - "spi_transfer of length %i exceed max length of %zu - needed to split transfers\n", - xfer->len, maxsize); - /* calculate how many we have to replace */ count = DIV_ROUND_UP(xfer->len, maxsize); @@ -2943,6 +2945,11 @@ int spi_setup(struct spi_device *spi) * so it is ignored here. */ bad_bits = spi->mode & ~(spi->controller->mode_bits | SPI_CS_WORD); + /* nothing prevents from working with active-high CS in case if it + * is driven by GPIO. + */ + if (gpio_is_valid(spi->cs_gpio)) + bad_bits &= ~SPI_CS_HIGH; ugly_bits = bad_bits & (SPI_TX_DUAL | SPI_TX_QUAD | SPI_TX_OCTAL | SPI_RX_DUAL | SPI_RX_QUAD | SPI_RX_OCTAL); @@ -2988,6 +2995,21 @@ int spi_setup(struct spi_device *spi) } EXPORT_SYMBOL_GPL(spi_setup); +/** + * spi_set_cs_timing - configure CS setup, hold, and inactive delays + * @spi: the device that requires specific CS timing configuration + * @setup: CS setup time in terms of clock count + * @hold: CS hold time in terms of clock count + * @inactive_dly: CS inactive delay between transfers in terms of clock count + */ +void spi_set_cs_timing(struct spi_device *spi, u8 setup, u8 hold, + u8 inactive_dly) +{ + if (spi->controller->set_cs_timing) + spi->controller->set_cs_timing(spi, setup, hold, inactive_dly); +} +EXPORT_SYMBOL_GPL(spi_set_cs_timing); + static int __spi_validate(struct spi_device *spi, struct spi_message *message) { struct spi_controller *ctlr = spi->controller; @@ -3062,8 +3084,6 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) if (!xfer->speed_hz) xfer->speed_hz = spi->max_speed_hz; - if (!xfer->speed_hz) - xfer->speed_hz = ctlr->max_speed_hz; if (ctlr->max_speed_hz && xfer->speed_hz > ctlr->max_speed_hz) xfer->speed_hz = ctlr->max_speed_hz; |