spi: prevent overriding established bus settings
authorMarcin Wojtas <mw@semihalf.com>
Thu, 21 Nov 2019 04:38:47 +0000 (05:38 +0100)
committerJagan Teki <jagan@amarulasolutions.com>
Mon, 27 Jan 2020 16:57:22 +0000 (22:27 +0530)
The SPI stack relies on a proper bus speed/mode configuration
by calling dm_spi_claim_bus(). However the hitherto code
allowed to accidentally override those settings in
the spi_get_bus_and_cs() routine.

The initially established speed could be discarded by using
the slave platdata, which turned out to be an issue on
the platforms whose slave maximum supported frequency
is not on par with the maximum frequency of the bus controller.

This patch fixes above issue by configuring the bus from
spi_get_bus_and_cs() only in case it was not done before.

Signed-off-by: Marcin Wojtas <mw@semihalf.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Acked-by: Jagan Teki <jagan@amarulasolutions.com>
drivers/spi/spi-uclass.c

index 5ced890..9208b16 100644 (file)
@@ -323,6 +323,7 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
 {
        struct udevice *bus, *dev;
        struct dm_spi_slave_platdata *plat;
+       struct spi_slave *slave;
        bool created = false;
        int ret;
 
@@ -378,19 +379,20 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
                slave->dev = dev;
        }
 
-       plat = dev_get_parent_platdata(dev);
+       slave = dev_get_parent_priv(dev);
 
-       /* get speed and mode from platdata when available */
-       if (plat->max_hz) {
-               speed = plat->max_hz;
-               mode = plat->mode;
+       /*
+        * In case the operation speed is not yet established by
+        * dm_spi_claim_bus() ensure the bus is configured properly.
+        */
+       if (!slave->speed) {
+               ret = spi_claim_bus(slave);
+               if (ret)
+                       goto err;
        }
-       ret = spi_set_speed_mode(bus, speed, mode);
-       if (ret)
-               goto err;
 
        *busp = bus;
-       *devp = dev_get_parent_priv(dev);
+       *devp = slave;
        debug("%s: bus=%p, slave=%p\n", __func__, bus, *devp);
 
        return 0;