mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 10:00:17 +00:00
spi: spi_register_controller(): free bus id on error paths
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>
This commit is contained in:
committed by
Mark Brown
parent
51bddd4501
commit
f9981d4f50
@@ -2645,7 +2645,7 @@ int spi_register_controller(struct spi_controller *ctlr)
|
|||||||
if (ctlr->use_gpio_descriptors) {
|
if (ctlr->use_gpio_descriptors) {
|
||||||
status = spi_get_gpio_descs(ctlr);
|
status = spi_get_gpio_descs(ctlr);
|
||||||
if (status)
|
if (status)
|
||||||
return status;
|
goto free_bus_id;
|
||||||
/*
|
/*
|
||||||
* A controller using GPIO descriptors always
|
* A controller using GPIO descriptors always
|
||||||
* supports SPI_CS_HIGH if need be.
|
* supports SPI_CS_HIGH if need be.
|
||||||
@@ -2655,7 +2655,7 @@ int spi_register_controller(struct spi_controller *ctlr)
|
|||||||
/* Legacy code path for GPIOs from DT */
|
/* Legacy code path for GPIOs from DT */
|
||||||
status = of_spi_get_gpio_numbers(ctlr);
|
status = of_spi_get_gpio_numbers(ctlr);
|
||||||
if (status)
|
if (status)
|
||||||
return status;
|
goto free_bus_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2663,17 +2663,14 @@ int spi_register_controller(struct spi_controller *ctlr)
|
|||||||
* Even if it's just one always-selected device, there must
|
* Even if it's just one always-selected device, there must
|
||||||
* be at least one chipselect.
|
* be at least one chipselect.
|
||||||
*/
|
*/
|
||||||
if (!ctlr->num_chipselect)
|
if (!ctlr->num_chipselect) {
|
||||||
return -EINVAL;
|
status = -EINVAL;
|
||||||
|
goto free_bus_id;
|
||||||
|
}
|
||||||
|
|
||||||
status = device_add(&ctlr->dev);
|
status = device_add(&ctlr->dev);
|
||||||
if (status < 0) {
|
if (status < 0)
|
||||||
/* free bus id */
|
goto free_bus_id;
|
||||||
mutex_lock(&board_lock);
|
|
||||||
idr_remove(&spi_master_idr, ctlr->bus_num);
|
|
||||||
mutex_unlock(&board_lock);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
dev_dbg(dev, "registered %s %s\n",
|
dev_dbg(dev, "registered %s %s\n",
|
||||||
spi_controller_is_slave(ctlr) ? "slave" : "master",
|
spi_controller_is_slave(ctlr) ? "slave" : "master",
|
||||||
dev_name(&ctlr->dev));
|
dev_name(&ctlr->dev));
|
||||||
@@ -2689,11 +2686,7 @@ int spi_register_controller(struct spi_controller *ctlr)
|
|||||||
status = spi_controller_initialize_queue(ctlr);
|
status = spi_controller_initialize_queue(ctlr);
|
||||||
if (status) {
|
if (status) {
|
||||||
device_del(&ctlr->dev);
|
device_del(&ctlr->dev);
|
||||||
/* free bus id */
|
goto free_bus_id;
|
||||||
mutex_lock(&board_lock);
|
|
||||||
idr_remove(&spi_master_idr, ctlr->bus_num);
|
|
||||||
mutex_unlock(&board_lock);
|
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* add statistics */
|
/* add statistics */
|
||||||
@@ -2708,7 +2701,12 @@ int spi_register_controller(struct spi_controller *ctlr)
|
|||||||
/* Register devices from the device tree and ACPI */
|
/* Register devices from the device tree and ACPI */
|
||||||
of_register_spi_devices(ctlr);
|
of_register_spi_devices(ctlr);
|
||||||
acpi_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;
|
return status;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(spi_register_controller);
|
EXPORT_SYMBOL_GPL(spi_register_controller);
|
||||||
|
|||||||
Reference in New Issue
Block a user