Skip to content

Commit d347b4a

Browse files
blocktrronbroonie
authored andcommitted
spi: sync up initial chipselect state
When initially probing the SPI slave device, the call for disabling an SPI device without the SPI_CS_HIGH flag is not applied, as the condition for checking whether or not the state to be applied equals the one currently set evaluates to true. This however might not necessarily be the case, as the chipselect might be active. Add a force flag to spi_set_cs which allows to override this early exit condition. Set it to false everywhere except when called from spi_setup to sync up the initial CS state. Fixes commit d40f0b6 ("spi: Avoid setting the chip select if we don't need to") Signed-off-by: David Bauer <mail@david-bauer.net> Link: https://lore.kernel.org/r/20210416195956.121811-1-mail@david-bauer.net Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 126bdb6 commit d347b4a

1 file changed

Lines changed: 8 additions & 8 deletions

File tree

drivers/spi/spi.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -786,15 +786,15 @@ int spi_register_board_info(struct spi_board_info const *info, unsigned n)
786786

787787
/*-------------------------------------------------------------------------*/
788788

789-
static void spi_set_cs(struct spi_device *spi, bool enable)
789+
static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
790790
{
791791
bool enable1 = enable;
792792

793793
/*
794794
* Avoid calling into the driver (or doing delays) if the chip select
795795
* isn't actually changing from the last time this was called.
796796
*/
797-
if ((spi->controller->last_cs_enable == enable) &&
797+
if (!force && (spi->controller->last_cs_enable == enable) &&
798798
(spi->controller->last_cs_mode_high == (spi->mode & SPI_CS_HIGH)))
799799
return;
800800

@@ -1244,7 +1244,7 @@ static int spi_transfer_one_message(struct spi_controller *ctlr,
12441244
struct spi_statistics *statm = &ctlr->statistics;
12451245
struct spi_statistics *stats = &msg->spi->statistics;
12461246

1247-
spi_set_cs(msg->spi, true);
1247+
spi_set_cs(msg->spi, true, false);
12481248

12491249
SPI_STATISTICS_INCREMENT_FIELD(statm, messages);
12501250
SPI_STATISTICS_INCREMENT_FIELD(stats, messages);
@@ -1312,9 +1312,9 @@ static int spi_transfer_one_message(struct spi_controller *ctlr,
13121312
&msg->transfers)) {
13131313
keep_cs = true;
13141314
} else {
1315-
spi_set_cs(msg->spi, false);
1315+
spi_set_cs(msg->spi, false, false);
13161316
_spi_transfer_cs_change_delay(msg, xfer);
1317-
spi_set_cs(msg->spi, true);
1317+
spi_set_cs(msg->spi, true, false);
13181318
}
13191319
}
13201320

@@ -1323,7 +1323,7 @@ static int spi_transfer_one_message(struct spi_controller *ctlr,
13231323

13241324
out:
13251325
if (ret != 0 || !keep_cs)
1326-
spi_set_cs(msg->spi, false);
1326+
spi_set_cs(msg->spi, false, false);
13271327

13281328
if (msg->status == -EINPROGRESS)
13291329
msg->status = ret;
@@ -3399,11 +3399,11 @@ int spi_setup(struct spi_device *spi)
33993399
*/
34003400
status = 0;
34013401

3402-
spi_set_cs(spi, false);
3402+
spi_set_cs(spi, false, true);
34033403
pm_runtime_mark_last_busy(spi->controller->dev.parent);
34043404
pm_runtime_put_autosuspend(spi->controller->dev.parent);
34053405
} else {
3406-
spi_set_cs(spi, false);
3406+
spi_set_cs(spi, false, true);
34073407
}
34083408

34093409
mutex_unlock(&spi->controller->io_mutex);

0 commit comments

Comments
 (0)