mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-16 08:44:21 +08:00
spi: spi_register_controller(): free bus id on error paths
[ Upstream commit f9981d4f50
]
Some error paths leave the bus id allocated. As a result the IDR
allocation will fail after a deferred probe. Fix by freeing the bus id
always on error.
Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com>
Message-Id: <20200304111740.27915-1-aaro.koskinen@nokia.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
af7dd05d7c
commit
0bc9de1b1c
@ -2452,7 +2452,7 @@ int spi_register_controller(struct spi_controller *ctlr)
|
||||
if (ctlr->use_gpio_descriptors) {
|
||||
status = spi_get_gpio_descs(ctlr);
|
||||
if (status)
|
||||
return status;
|
||||
goto free_bus_id;
|
||||
/*
|
||||
* A controller using GPIO descriptors always
|
||||
* supports SPI_CS_HIGH if need be.
|
||||
@ -2462,7 +2462,7 @@ int spi_register_controller(struct spi_controller *ctlr)
|
||||
/* Legacy code path for GPIOs from DT */
|
||||
status = of_spi_get_gpio_numbers(ctlr);
|
||||
if (status)
|
||||
return status;
|
||||
goto free_bus_id;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2470,17 +2470,14 @@ int spi_register_controller(struct spi_controller *ctlr)
|
||||
* Even if it's just one always-selected device, there must
|
||||
* be at least one chipselect.
|
||||
*/
|
||||
if (!ctlr->num_chipselect)
|
||||
return -EINVAL;
|
||||
if (!ctlr->num_chipselect) {
|
||||
status = -EINVAL;
|
||||
goto free_bus_id;
|
||||
}
|
||||
|
||||
status = device_add(&ctlr->dev);
|
||||
if (status < 0) {
|
||||
/* free bus id */
|
||||
mutex_lock(&board_lock);
|
||||
idr_remove(&spi_master_idr, ctlr->bus_num);
|
||||
mutex_unlock(&board_lock);
|
||||
goto done;
|
||||
}
|
||||
if (status < 0)
|
||||
goto free_bus_id;
|
||||
dev_dbg(dev, "registered %s %s\n",
|
||||
spi_controller_is_slave(ctlr) ? "slave" : "master",
|
||||
dev_name(&ctlr->dev));
|
||||
@ -2496,11 +2493,7 @@ int spi_register_controller(struct spi_controller *ctlr)
|
||||
status = spi_controller_initialize_queue(ctlr);
|
||||
if (status) {
|
||||
device_del(&ctlr->dev);
|
||||
/* free bus id */
|
||||
mutex_lock(&board_lock);
|
||||
idr_remove(&spi_master_idr, ctlr->bus_num);
|
||||
mutex_unlock(&board_lock);
|
||||
goto done;
|
||||
goto free_bus_id;
|
||||
}
|
||||
}
|
||||
/* add statistics */
|
||||
@ -2515,7 +2508,12 @@ int spi_register_controller(struct spi_controller *ctlr)
|
||||
/* Register devices from the device tree and ACPI */
|
||||
of_register_spi_devices(ctlr);
|
||||
acpi_register_spi_devices(ctlr);
|
||||
done:
|
||||
return status;
|
||||
|
||||
free_bus_id:
|
||||
mutex_lock(&board_lock);
|
||||
idr_remove(&spi_master_idr, ctlr->bus_num);
|
||||
mutex_unlock(&board_lock);
|
||||
return status;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(spi_register_controller);
|
||||
|
Loading…
Reference in New Issue
Block a user