| From 6422c792314aae98fff0a36846412dac04c63530 Mon Sep 17 00:00:00 2001 |
| From: Aaro Koskinen <aaro.koskinen@nokia.com> |
| Date: Wed, 4 Mar 2020 13:17:40 +0200 |
| Subject: [PATCH] spi: spi_register_controller(): free bus id on error paths |
| |
| commit f9981d4f50b475d7dbb70f3022b87a3c8bba9fd6 upstream. |
| |
| 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: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c |
| index 6ae55113672f..e32cc591f409 100644 |
| --- a/drivers/spi/spi.c |
| +++ b/drivers/spi/spi.c |
| @@ -2343,7 +2343,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. |
| @@ -2353,7 +2353,7 @@ int spi_register_controller(struct spi_controller *ctlr) |
| /* Legacy code path for GPIOs from DT */ |
| status = of_spi_register_master(ctlr); |
| if (status) |
| - return status; |
| + goto free_bus_id; |
| } |
| } |
| |
| @@ -2361,17 +2361,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)); |
| @@ -2387,11 +2384,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 */ |
| @@ -2406,7 +2399,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); |
| -- |
| 2.7.4 |
| |