summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorBin Meng <bmeng.cn@gmail.com>2019-09-09 06:00:02 -0700
committerJagan Teki <jagan@amarulasolutions.com>2020-01-27 22:27:21 +0530
commit7bacce524d48594dae399f9ee9280ab105f6c8cf (patch)
treea9cdb8e947d511b199db7647361b272ea6262a27 /drivers
parent383fded70c4f14370bc5525bdb9f547393876e31 (diff)
downloadu-boot-7bacce524d48594dae399f9ee9280ab105f6c8cf.tar.gz
dm: spi: Check cs number before accessing slaves
Add chip select number check in spi_find_chip_select(). Signed-off-by: Bin Meng <bmeng.cn@gmail.com> Tested-by: Jagan Teki <jagan@amarulasolutions.com> # SoPine
Diffstat (limited to 'drivers')
-rw-r--r--drivers/spi/spi-uclass.c45
1 files changed, 26 insertions, 19 deletions
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index 0ca108ee3d..5ced8905f8 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -224,7 +224,32 @@ int spi_chip_select(struct udevice *dev)
int spi_find_chip_select(struct udevice *bus, int cs, struct udevice **devp)
{
+ struct dm_spi_ops *ops;
+ struct spi_cs_info info;
struct udevice *dev;
+ int ret;
+
+ /*
+ * Ask the driver. For the moment we don't have CS info.
+ * When we do we could provide the driver with a helper function
+ * to figure out what chip selects are valid, or just handle the
+ * request.
+ */
+ ops = spi_get_ops(bus);
+ if (ops->cs_info) {
+ ret = ops->cs_info(bus, cs, &info);
+ } else {
+ /*
+ * We could assume there is at least one valid chip select.
+ * The driver didn't care enough to tell us.
+ */
+ ret = 0;
+ }
+
+ if (ret) {
+ printf("Invalid cs %d (err=%d)\n", cs, ret);
+ return ret;
+ }
for (device_find_first_child(bus, &dev); dev;
device_find_next_child(&dev)) {
@@ -259,7 +284,6 @@ int spi_cs_is_valid(unsigned int busnum, unsigned int cs)
int spi_cs_info(struct udevice *bus, uint cs, struct spi_cs_info *info)
{
struct spi_cs_info local_info;
- struct dm_spi_ops *ops;
int ret;
if (!info)
@@ -268,24 +292,7 @@ int spi_cs_info(struct udevice *bus, uint cs, struct spi_cs_info *info)
/* If there is a device attached, return it */
info->dev = NULL;
ret = spi_find_chip_select(bus, cs, &info->dev);
- if (!ret)
- return 0;
-
- /*
- * Otherwise ask the driver. For the moment we don't have CS info.
- * When we do we could provide the driver with a helper function
- * to figure out what chip selects are valid, or just handle the
- * request.
- */
- ops = spi_get_ops(bus);
- if (ops->cs_info)
- return ops->cs_info(bus, cs, info);
-
- /*
- * We could assume there is at least one valid chip select.
- * The driver didn't care enough to tell us.
- */
- return 0;
+ return ret == -ENODEV ? 0 : ret;
}
int spi_find_bus_and_cs(int busnum, int cs, struct udevice **busp,