diff options
author | Mark Brown <broonie@kernel.org> | 2019-05-02 05:20:29 +0300 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2019-05-02 05:20:29 +0300 |
commit | 2e5f081003f033d37be3faf052aaccc8b6a44aa5 (patch) | |
tree | 6d07a9bfff47b20f997ecce96162b8ca9cf7b19c /drivers/spi/spi.c | |
parent | 58b860ed4a77d9cb17b78e663a0341b79a12e240 (diff) | |
parent | d61ad23cb3be09ff4956e9b9794134456522817f (diff) | |
download | linux-2e5f081003f033d37be3faf052aaccc8b6a44aa5.tar.xz |
Merge branch 'spi-5.2' into spi-next
Diffstat (limited to 'drivers/spi/spi.c')
-rw-r--r-- | drivers/spi/spi.c | 72 |
1 files changed, 44 insertions, 28 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 7b6494bd8a9b..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" @@ -1179,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; } @@ -2265,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) @@ -2279,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 */ @@ -2353,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 */ @@ -2785,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); @@ -2947,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); @@ -2992,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; @@ -3066,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; |