]> git.proxmox.com Git - mirror_ubuntu-disco-kernel.git/commitdiff
spi: fix IDR collision on systems with both fixed and dynamic SPI bus numbers
authorLucas Stach <l.stach@pengutronix.de>
Mon, 16 Oct 2017 10:27:58 +0000 (12:27 +0200)
committerMark Brown <broonie@kernel.org>
Fri, 3 Nov 2017 11:08:18 +0000 (12:08 +0100)
On systems where some controllers get a dynamic ID assigned and some have
a fixed number from DT, the current implemention might run into an IDR
collision if the dynamic controllers gets probed first and get an IDR number,
which is later requested by the controller with the fixed numbering. When
this happens the fixed controller will fail to register with the SPI core.

Fix this by skipping all known alias numbers when assigning the dynamic IDs.

Fixes: 9b61e302210e (spi: Pick spi bus number from Linux idr or spi alias)
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spi.c

index 759c9725495a533f16e737ff51fb287f265a486d..3ff0ee88c467a58faa9c6a1544fd620e6852b250 100644 (file)
@@ -45,7 +45,6 @@
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/spi.h>
-#define SPI_DYN_FIRST_BUS_NUM 0
 
 static DEFINE_IDR(spi_master_idr);
 
@@ -2086,7 +2085,7 @@ int spi_register_controller(struct spi_controller *ctlr)
        struct device           *dev = ctlr->dev.parent;
        struct boardinfo        *bi;
        int                     status = -ENODEV;
-       int                     id;
+       int                     id, first_dynamic;
 
        if (!dev)
                return -ENODEV;
@@ -2116,9 +2115,15 @@ int spi_register_controller(struct spi_controller *ctlr)
                }
        }
        if (ctlr->bus_num < 0) {
+               first_dynamic = of_alias_get_highest_id("spi");
+               if (first_dynamic < 0)
+                       first_dynamic = 0;
+               else
+                       first_dynamic++;
+
                mutex_lock(&board_lock);
-               id = idr_alloc(&spi_master_idr, ctlr, SPI_DYN_FIRST_BUS_NUM, 0,
-                              GFP_KERNEL);
+               id = idr_alloc(&spi_master_idr, ctlr, first_dynamic,
+                              0, GFP_KERNEL);
                mutex_unlock(&board_lock);
                if (WARN(id < 0, "couldn't get idr"))
                        return id;