summaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorLucas Stach <l.stach@pengutronix.de>2017-10-16 06:27:58 -0400
committerMark Brown <broonie@kernel.org>2017-10-16 16:02:54 -0400
commit226584aedd94acd61ffa51fb69bcf6b3309a7b8f (patch)
treefa8fbb84c1def9272f16dd01dc4ae9d707138e66 /drivers/spi
parent2bd6bf03f4c1c59381d62c61d03f6cc3fe71f66e (diff)
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: 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>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 6e65524cbfd9..e8b5a5e21b2e 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -45,7 +45,6 @@
45 45
46#define CREATE_TRACE_POINTS 46#define CREATE_TRACE_POINTS
47#include <trace/events/spi.h> 47#include <trace/events/spi.h>
48#define SPI_DYN_FIRST_BUS_NUM 0
49 48
50static DEFINE_IDR(spi_master_idr); 49static DEFINE_IDR(spi_master_idr);
51 50
@@ -2086,7 +2085,7 @@ int spi_register_controller(struct spi_controller *ctlr)
2086 struct device *dev = ctlr->dev.parent; 2085 struct device *dev = ctlr->dev.parent;
2087 struct boardinfo *bi; 2086 struct boardinfo *bi;
2088 int status = -ENODEV; 2087 int status = -ENODEV;
2089 int id; 2088 int id, first_dynamic;
2090 2089
2091 if (!dev) 2090 if (!dev)
2092 return -ENODEV; 2091 return -ENODEV;
@@ -2116,9 +2115,15 @@ int spi_register_controller(struct spi_controller *ctlr)
2116 } 2115 }
2117 } 2116 }
2118 if (ctlr->bus_num < 0) { 2117 if (ctlr->bus_num < 0) {
2118 first_dynamic = of_alias_get_highest_id("spi");
2119 if (first_dynamic < 0)
2120 first_dynamic = 0;
2121 else
2122 first_dynamic++;
2123
2119 mutex_lock(&board_lock); 2124 mutex_lock(&board_lock);
2120 id = idr_alloc(&spi_master_idr, ctlr, SPI_DYN_FIRST_BUS_NUM, 0, 2125 id = idr_alloc(&spi_master_idr, ctlr, first_dynamic,
2121 GFP_KERNEL); 2126 0, GFP_KERNEL);
2122 mutex_unlock(&board_lock); 2127 mutex_unlock(&board_lock);
2123 if (WARN(id < 0, "couldn't get idr")) 2128 if (WARN(id < 0, "couldn't get idr"))
2124 return id; 2129 return id;