mpc8xxx_spi: put max_cs to use
authorRasmus Villemoes <rasmus.villemoes@prevas.dk>
Tue, 11 Feb 2020 15:20:24 +0000 (15:20 +0000)
committerTom Rini <trini@konsulko.com>
Tue, 31 Mar 2020 14:06:52 +0000 (10:06 -0400)
Currently, max_cs is write-only; it's just set in
mpc8xxx_spi_ofdata_to_platdata and not otherwise used.

My mpc8309 was always resetting during an "sf probe 0". It turns out
dm_gpio_set_dir_flags() was being called with garbage, since nothing
had initialized priv->gpios[0] - our device tree used "cs-gpios"
rather than "gpios", so gpio_request_list_by_name() had returned 0.

That would have been a lot easier to figure out if the chip select
index was sanity checked, so rename max_cs to cs_count, and reject a
xfer with a too large cs index.

Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
drivers/spi/mpc8xxx_spi.c

index 1c7bf10f91e37ccd83f314c0b9b73b230c6fef7d..ac4d0a9baef59927292effb927be49b6cb662734 100644 (file)
@@ -35,7 +35,7 @@ enum {
 struct mpc8xxx_priv {
        spi8xxx_t *spi;
        struct gpio_desc gpios[16];
-       int max_cs;
+       int cs_count;
 };
 
 static inline u32 to_prescale_mod(u32 val)
@@ -74,7 +74,7 @@ static int mpc8xxx_spi_ofdata_to_platdata(struct udevice *dev)
        if (ret < 0)
                return -EINVAL;
 
-       priv->max_cs = ret;
+       priv->cs_count = ret;
 
        return 0;
 }
@@ -131,6 +131,11 @@ static int mpc8xxx_spi_xfer(struct udevice *dev, uint bitlen,
 
        debug("%s: slave %s:%u dout %08X din %08X bitlen %u\n", __func__,
              bus->name, platdata->cs, *(uint *)dout, *(uint *)din, bitlen);
+       if (platdata->cs >= priv->cs_count) {
+               dev_err(dev, "chip select index %d too large (cs_count=%d)\n",
+                       platdata->cs, priv->cs_count);
+               return -EINVAL;
+       }
 
        if (flags & SPI_XFER_BEGIN)
                mpc8xxx_spi_cs_activate(dev);