Commit 44189ec1 authored by Stefan Roese's avatar Stefan Roese Committed by Jiri Slaby

spi: fsl: Fix problem with multi message transfers

commit 4302a596 upstream.

When used via spidev with more than one messages to tranfer via
SPI_IOC_MESSAGE the current implementation would return with
-EINVAL, since bits_per_word and speed_hz are set in all
transfer structs. And in the 2nd loop status will stay at
-EINVAL as its not overwritten again via fsl_spi_setup_transfer().

This patch changes this behavious by first checking if one of
the messages uses different settings. If this is the case
the function will return with -EINVAL. If not, the messages
are transferred correctly.
Signed-off-by: default avatarStefan Roese <sr@denx.de>
Signed-off-by: default avatarMark Brown <broonie@linaro.org>
Cc: Esben Haabendal <esbenhaabendal@gmail.com>
Signed-off-by: default avatarJiri Slaby <jslaby@suse.cz>
parent 0f069ee1
...@@ -362,18 +362,28 @@ static int fsl_spi_bufs(struct spi_device *spi, struct spi_transfer *t, ...@@ -362,18 +362,28 @@ static int fsl_spi_bufs(struct spi_device *spi, struct spi_transfer *t,
static void fsl_spi_do_one_msg(struct spi_message *m) static void fsl_spi_do_one_msg(struct spi_message *m)
{ {
struct spi_device *spi = m->spi; struct spi_device *spi = m->spi;
struct spi_transfer *t; struct spi_transfer *t, *first;
unsigned int cs_change; unsigned int cs_change;
const int nsecs = 50; const int nsecs = 50;
int status; int status;
cs_change = 1; /* Don't allow changes if CS is active */
status = 0; first = list_first_entry(&m->transfers, struct spi_transfer,
transfer_list);
list_for_each_entry(t, &m->transfers, transfer_list) { list_for_each_entry(t, &m->transfers, transfer_list) {
if (t->bits_per_word || t->speed_hz) { if ((first->bits_per_word != t->bits_per_word) ||
/* Don't allow changes if CS is active */ (first->speed_hz != t->speed_hz)) {
status = -EINVAL; status = -EINVAL;
dev_err(&spi->dev,
"bits_per_word/speed_hz should be same for the same SPI transfer\n");
return;
}
}
cs_change = 1;
status = -EINVAL;
list_for_each_entry(t, &m->transfers, transfer_list) {
if (t->bits_per_word || t->speed_hz) {
if (cs_change) if (cs_change)
status = fsl_spi_setup_transfer(spi, t); status = fsl_spi_setup_transfer(spi, t);
if (status < 0) if (status < 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment