Skip to content

Commit ffe6f38

Browse files
Rasmus Villemoesgregkh
authored andcommitted
spi: spi-fsl-spi: allow changing bits_per_word while CS is still active
commit a798a70 upstream. Commit c9bfcb3 (spi_mpc83xx: much improved driver) introduced logic to ensure bits_per_word and speed_hz stay the same for a series of spi_transfers with CS active, arguing that The current driver may cause glitches on SPI CLK line since one must disable the SPI controller before changing any HW settings. This sounds quite reasonable. So this is a quite naive attempt at relaxing this sanity checking to only ensure that speed_hz is constant - in the faint hope that if we do not causes changes to the clock-related fields of the SPMODE register (DIV16 and PM), those glitches won't appear. The purpose of this change is to allow automatically optimizing large transfers to use 32 bits-per-word; taking one interrupt for every byte is extremely slow. Signed-off-by: Rasmus Villemoes <[email protected]> Signed-off-by: Mark Brown <[email protected]> Cc: Christophe Leroy <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 3793809 commit ffe6f38

File tree

1 file changed

+6
-5
lines changed

1 file changed

+6
-5
lines changed

drivers/spi/spi-fsl-spi.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ static int fsl_spi_do_one_msg(struct spi_master *master,
339339
struct spi_transfer *t, *first;
340340
unsigned int cs_change;
341341
const int nsecs = 50;
342-
int status;
342+
int status, last_bpw;
343343

344344
/*
345345
* In CPU mode, optimize large byte transfers to use larger
@@ -378,21 +378,22 @@ static int fsl_spi_do_one_msg(struct spi_master *master,
378378
if (cs_change)
379379
first = t;
380380
cs_change = t->cs_change;
381-
if ((first->bits_per_word != t->bits_per_word) ||
382-
(first->speed_hz != t->speed_hz)) {
381+
if (first->speed_hz != t->speed_hz) {
383382
dev_err(&spi->dev,
384-
"bits_per_word/speed_hz cannot change while CS is active\n");
383+
"speed_hz cannot change while CS is active\n");
385384
return -EINVAL;
386385
}
387386
}
388387

388+
last_bpw = -1;
389389
cs_change = 1;
390390
status = -EINVAL;
391391
list_for_each_entry(t, &m->transfers, transfer_list) {
392-
if (cs_change)
392+
if (cs_change || last_bpw != t->bits_per_word)
393393
status = fsl_spi_setup_transfer(spi, t);
394394
if (status < 0)
395395
break;
396+
last_bpw = t->bits_per_word;
396397

397398
if (cs_change) {
398399
fsl_spi_chipselect(spi, BITBANG_CS_ACTIVE);

0 commit comments

Comments
 (0)