Skip to content

Commit 72a85e2

Browse files
committed
Merge tag 'spi-fix-v6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi fix from Mark Brown: "One driver specific change here which handles the case where a SPI device for some reason tries to change the bus speed during a message on fsl_spi hardware, this should be very unusual" * tag 'spi-fix-v6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: spi: fsl_spi: Don't change speed while chipselect is active
2 parents 0a023cb + 3b553e0 commit 72a85e2

File tree

1 file changed

+16
-3
lines changed

1 file changed

+16
-3
lines changed

drivers/spi/spi-fsl-spi.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -333,13 +333,26 @@ static int fsl_spi_prepare_message(struct spi_controller *ctlr,
333333
{
334334
struct mpc8xxx_spi *mpc8xxx_spi = spi_controller_get_devdata(ctlr);
335335
struct spi_transfer *t;
336+
struct spi_transfer *first;
337+
338+
first = list_first_entry(&m->transfers, struct spi_transfer,
339+
transfer_list);
336340

337341
/*
338342
* In CPU mode, optimize large byte transfers to use larger
339343
* bits_per_word values to reduce number of interrupts taken.
344+
*
345+
* Some glitches can appear on the SPI clock when the mode changes.
346+
* Check that there is no speed change during the transfer and set it up
347+
* now to change the mode without having a chip-select asserted.
340348
*/
341-
if (!(mpc8xxx_spi->flags & SPI_CPM_MODE)) {
342-
list_for_each_entry(t, &m->transfers, transfer_list) {
349+
list_for_each_entry(t, &m->transfers, transfer_list) {
350+
if (t->speed_hz != first->speed_hz) {
351+
dev_err(&m->spi->dev,
352+
"speed_hz cannot change during message.\n");
353+
return -EINVAL;
354+
}
355+
if (!(mpc8xxx_spi->flags & SPI_CPM_MODE)) {
343356
if (t->len < 256 || t->bits_per_word != 8)
344357
continue;
345358
if ((t->len & 3) == 0)
@@ -348,7 +361,7 @@ static int fsl_spi_prepare_message(struct spi_controller *ctlr,
348361
t->bits_per_word = 16;
349362
}
350363
}
351-
return 0;
364+
return fsl_spi_setup_transfer(m->spi, first);
352365
}
353366

354367
static int fsl_spi_transfer_one(struct spi_controller *controller,

0 commit comments

Comments
 (0)