[2/2] spi: spidev: fix a max speed setting
diff mbox series

Message ID 20200220141143.3902922-3-oleksandr.suvorov@toradex.com
State New, archived
Headers show
Series
  • trivial fixes for fsl-spi and spidev
Related show

Commit Message

Oleksandr Suvorov Feb. 20, 2020, 2:11 p.m. UTC
SPI_IOC_WR_MAX_SPEED_HZ command always sets spi->max_speed_hz
to the initial value come from DT.
It leads to set a wrong max speed with IOCTL call.

Fix the logic of a max speed assignment.

Signed-off-by: Oleksandr Suvorov <oleksandr.suvorov@toradex.com>
---

 drivers/spi/spidev.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

Comments

Mark Brown Feb. 20, 2020, 6:42 p.m. UTC | #1
On Thu, Feb 20, 2020 at 02:11:51PM +0000, Oleksandr Suvorov wrote:
> SPI_IOC_WR_MAX_SPEED_HZ command always sets spi->max_speed_hz
> to the initial value come from DT.

This is intentional.  It's doing a call to spi_setup() then restoring
the original value, the goal being just to run spi_setup() with the new
value - it's not really a good idea to change the maximum speed in the
first place.

> It leads to set a wrong max speed with IOCTL call.

In what way does it lead to the wrong speed being set?

> Fix the logic of a max speed assignment.

If the expectation is that the default speed should be changed for the
device this should be handled at the spidev level rather than in the
core.
Oleksandr Suvorov Feb. 21, 2020, 12:43 p.m. UTC | #2
Hi Mark,

On Thu, Feb 20, 2020 at 8:42 PM Mark Brown <broonie@kernel.org> wrote:
>
> On Thu, Feb 20, 2020 at 02:11:51PM +0000, Oleksandr Suvorov wrote:
> > SPI_IOC_WR_MAX_SPEED_HZ command always sets spi->max_speed_hz
> > the initial value come from DT.
>
> This is intentional.  It's doing a call to spi_setup() then restoring
> the original value, the goal being just to run spi_setup() with the new
> value - it's not really a good idea to change the maximum speed in the
> first place.

Now I see it.
>
> > It leads to set a wrong max speed with IOCTL call.
> In what way does it lead to the wrong speed being set?

After all, I reviewed the code and found out that the problem is not
in spidev_ioctl,
the problem is in spidev_message()'s debug message :)
The real code is ok:

drivers/spi/spidev.c: spidev_message():
...
                 k_tmp->speed_hz = u_tmp->speed_hz;
                 if (!k_tmp->speed_hz)
                        k_tmp->speed_hz = spidev->speed_hz;
...

but the debug message takes wrong value:
drivers/spi/spidev.c: spidev_message():
...
              dev_info(&spidev->spi->dev,
                      "  xfer len %u %s%s%s%dbits %u usec %uHz
(speed_hz=%d max_speed_hz=%d)\n",
                        u_tmp->len,
                        u_tmp->rx_buf ? "rx " : "",
                        u_tmp->tx_buf ? "tx " : "",
                        u_tmp->cs_change ? "cs " : "",
                        u_tmp->bits_per_word ? : spidev->spi->bits_per_word,
                        u_tmp->delay_usecs,
>>>                        u_tmp->speed_hz ? : spidev->spi->max_speed_hz);
...
It leads to debug messages like:

[ 1227.512806] spidev spi0.0: setup mode 0, 32 bits/w, 1000000 Hz max --> 0
[ 1227.541749] spidev spi0.0:   xfer len 4096 tx 32bits 0 usec 10000000Hz
..
[ 1227.616165] spidev spi0.0: setup mode 0, 32 bits/w, 2000000 Hz max --> 0
[ 1227.645095] spidev spi0.0:   xfer len 4096 tx 32bits 0 usec 10000000Hz
...
[ 1227.702714] spidev spi0.0: setup mode 0, 32 bits/w, 20000000 Hz max --> 0
[ 1227.731801] spidev spi0.0:   xfer len 4096 tx 32bits 0 usec 10000000Hz
...
So if one passes the message (using ioctl instead of write to fd) with
empty speed_hz,
the debug message tells the wrong real speed. It forced me to think in
the wrong direction.

> > Fix the logic of a max speed assignment.
>
> If the expectation is that the default speed should be changed for the
> device this should be handled at the spidev level rather than in the
> core.

Agree. I fixed the wrong place :)
I'll replace this patch with better one.

Thanx!

Patch
diff mbox series

diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
index 1e217e3e9486..b9b3ac70eb18 100644
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -449,11 +449,13 @@  spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 
 			spi->max_speed_hz = tmp;
 			retval = spi_setup(spi);
-			if (retval >= 0)
+			if (retval) {
+				spi->max_speed_hz = save;
+			} else {
 				spidev->speed_hz = tmp;
-			else
-				dev_dbg(&spi->dev, "%d Hz (max)\n", tmp);
-			spi->max_speed_hz = save;
+				dev_dbg(&spi->dev, "%d Hz (max)\n",
+					spidev->speed_hz);
+			}
 		}
 		break;