Unverified Commit f9981d4f authored by Aaro Koskinen's avatar Aaro Koskinen Committed by Mark Brown
Browse files

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: default avatarAaro Koskinen <aaro.koskinen@nokia.com>
Message-Id: <20200304111740.27915-1-aaro.koskinen@nokia.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 51bddd45
Loading
Loading
Loading
Loading
+15 −17
Original line number Diff line number Diff line
@@ -2645,7 +2645,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.
@@ -2655,7 +2655,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;
		}
	}

@@ -2663,17 +2663,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));
@@ -2689,11 +2686,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 */
@@ -2708,7 +2701,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);