mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 03:11:11 -04:00
spi: fix resource leaks on device setup failure
Johan Hovold <johan@kernel.org> says: Make sure to call controller cleanup() if spi_setup() fails while registering a device to avoid leaking any resources allocated by setup().
This commit is contained in:
@@ -43,6 +43,8 @@ EXPORT_TRACEPOINT_SYMBOL(spi_transfer_stop);
|
||||
|
||||
#include "internals.h"
|
||||
|
||||
static int __spi_setup(struct spi_device *spi, bool initial_setup);
|
||||
|
||||
static DEFINE_IDR(spi_controller_idr);
|
||||
|
||||
static void spidev_release(struct device *dev)
|
||||
@@ -743,7 +745,7 @@ static int __spi_add_device(struct spi_device *spi, struct spi_device *parent)
|
||||
* normally rely on the device being setup. Devices
|
||||
* using SPI_CS_HIGH can't coexist well otherwise...
|
||||
*/
|
||||
status = spi_setup(spi);
|
||||
status = __spi_setup(spi, true);
|
||||
if (status < 0) {
|
||||
dev_err(dev, "can't setup %s, status %d\n",
|
||||
dev_name(&spi->dev), status);
|
||||
@@ -4049,27 +4051,7 @@ static int spi_set_cs_timing(struct spi_device *spi)
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* spi_setup - setup SPI mode and clock rate
|
||||
* @spi: the device whose settings are being modified
|
||||
* Context: can sleep, and no requests are queued to the device
|
||||
*
|
||||
* SPI protocol drivers may need to update the transfer mode if the
|
||||
* device doesn't work with its default. They may likewise need
|
||||
* to update clock rates or word sizes from initial values. This function
|
||||
* changes those settings, and must be called from a context that can sleep.
|
||||
* Except for SPI_CS_HIGH, which takes effect immediately, the changes take
|
||||
* effect the next time the device is selected and data is transferred to
|
||||
* or from it. When this function returns, the SPI device is deselected.
|
||||
*
|
||||
* Note that this call will fail if the protocol driver specifies an option
|
||||
* that the underlying controller or its driver does not support. For
|
||||
* example, not all hardware supports wire transfers using nine bit words,
|
||||
* LSB-first wire encoding, or active-high chipselects.
|
||||
*
|
||||
* Return: zero on success, else a negative error code.
|
||||
*/
|
||||
int spi_setup(struct spi_device *spi)
|
||||
static int __spi_setup(struct spi_device *spi, bool initial_setup)
|
||||
{
|
||||
unsigned bad_bits, ugly_bits;
|
||||
int status;
|
||||
@@ -4154,7 +4136,7 @@ int spi_setup(struct spi_device *spi)
|
||||
status = spi_set_cs_timing(spi);
|
||||
if (status) {
|
||||
mutex_unlock(&spi->controller->io_mutex);
|
||||
return status;
|
||||
goto err_cleanup;
|
||||
}
|
||||
|
||||
if (spi->controller->auto_runtime_pm && spi->controller->set_cs) {
|
||||
@@ -4163,7 +4145,7 @@ int spi_setup(struct spi_device *spi)
|
||||
mutex_unlock(&spi->controller->io_mutex);
|
||||
dev_err(&spi->controller->dev, "Failed to power device: %d\n",
|
||||
status);
|
||||
return status;
|
||||
goto err_cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4199,6 +4181,37 @@ int spi_setup(struct spi_device *spi)
|
||||
status);
|
||||
|
||||
return status;
|
||||
|
||||
err_cleanup:
|
||||
if (initial_setup)
|
||||
spi_cleanup(spi);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* spi_setup - setup SPI mode and clock rate
|
||||
* @spi: the device whose settings are being modified
|
||||
* Context: can sleep, and no requests are queued to the device
|
||||
*
|
||||
* SPI protocol drivers may need to update the transfer mode if the
|
||||
* device doesn't work with its default. They may likewise need
|
||||
* to update clock rates or word sizes from initial values. This function
|
||||
* changes those settings, and must be called from a context that can sleep.
|
||||
* Except for SPI_CS_HIGH, which takes effect immediately, the changes take
|
||||
* effect the next time the device is selected and data is transferred to
|
||||
* or from it. When this function returns, the SPI device is deselected.
|
||||
*
|
||||
* Note that this call will fail if the protocol driver specifies an option
|
||||
* that the underlying controller or its driver does not support. For
|
||||
* example, not all hardware supports wire transfers using nine bit words,
|
||||
* LSB-first wire encoding, or active-high chipselects.
|
||||
*
|
||||
* Return: zero on success, else a negative error code.
|
||||
*/
|
||||
int spi_setup(struct spi_device *spi)
|
||||
{
|
||||
return __spi_setup(spi, false);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(spi_setup);
|
||||
|
||||
|
||||
@@ -701,7 +701,7 @@ struct spi_controller {
|
||||
int (*transfer)(struct spi_device *spi,
|
||||
struct spi_message *mesg);
|
||||
|
||||
/* Called on release() to free memory provided by spi_controller */
|
||||
/* Called on deregistration to free memory provided by spi_controller */
|
||||
void (*cleanup)(struct spi_device *spi);
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user