diff mbox

spi: fix IDR collision on systems with both fixed and dynamic SPI bus numbers

Message ID 20171013155946.1486-1-l.stach@pengutronix.de (mailing list archive)
State Accepted
Commit 9ce70d49fa80b95a029c16432270f4edbbd2a953
Headers show

Commit Message

Lucas Stach Oct. 13, 2017, 3:59 p.m. UTC
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>
---
 drivers/spi/spi.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

Comments

Mark Brown Oct. 13, 2017, 4:55 p.m. UTC | #1
On Fri, Oct 13, 2017 at 05:59:46PM +0200, Lucas Stach wrote:

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

> -		id = idr_alloc(&spi_master_idr, ctlr, SPI_DYN_FIRST_BUS_NUM, 0,
> -			       GFP_KERNEL);
> +		id = idr_alloc(&spi_master_idr, ctlr,
> +			       of_alias_get_highest_id("spi") + 1,
> +			       0, GFP_KERNEL);

I'll apply this but I'm wondering if we want to have the static bus
number allocation also allocate that number out of the IDR so the IDR
code handles things more transparently.  Feels like it's more trouble
than it's worth though, this should work fine.  I'm also worrying about
the case where IDR allocated a number before a static assignment got to
it...  not much we can do to guarantee that we avoid that case though.
diff mbox

Patch

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 6e65524cbfd9..0483410e7cb3 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -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);
 
@@ -2117,8 +2116,9 @@  int spi_register_controller(struct spi_controller *ctlr)
 	}
 	if (ctlr->bus_num < 0) {
 		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,
+			       of_alias_get_highest_id("spi") + 1,
+			       0, GFP_KERNEL);
 		mutex_unlock(&board_lock);
 		if (WARN(id < 0, "couldn't get idr"))
 			return id;