Commit 42bdd706 authored by Lucas Stach's avatar Lucas Stach Committed by Mark Brown

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

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: 9b61e302 (spi: Pick spi bus number from Linux idr or spi alias)
Signed-off-by: default avatarLucas Stach <l.stach@pengutronix.de>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 67f7b278
...@@ -45,7 +45,6 @@ ...@@ -45,7 +45,6 @@
#define CREATE_TRACE_POINTS #define CREATE_TRACE_POINTS
#include <trace/events/spi.h> #include <trace/events/spi.h>
#define SPI_DYN_FIRST_BUS_NUM 0
static DEFINE_IDR(spi_master_idr); static DEFINE_IDR(spi_master_idr);
...@@ -2086,7 +2085,7 @@ int spi_register_controller(struct spi_controller *ctlr) ...@@ -2086,7 +2085,7 @@ int spi_register_controller(struct spi_controller *ctlr)
struct device *dev = ctlr->dev.parent; struct device *dev = ctlr->dev.parent;
struct boardinfo *bi; struct boardinfo *bi;
int status = -ENODEV; int status = -ENODEV;
int id; int id, first_dynamic;
if (!dev) if (!dev)
return -ENODEV; return -ENODEV;
...@@ -2116,9 +2115,15 @@ int spi_register_controller(struct spi_controller *ctlr) ...@@ -2116,9 +2115,15 @@ int spi_register_controller(struct spi_controller *ctlr)
} }
} }
if (ctlr->bus_num < 0) { 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); mutex_lock(&board_lock);
id = idr_alloc(&spi_master_idr, ctlr, SPI_DYN_FIRST_BUS_NUM, 0, id = idr_alloc(&spi_master_idr, ctlr, first_dynamic,
GFP_KERNEL); 0, GFP_KERNEL);
mutex_unlock(&board_lock); mutex_unlock(&board_lock);
if (WARN(id < 0, "couldn't get idr")) if (WARN(id < 0, "couldn't get idr"))
return id; return id;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment