From: Yi Li <[email protected]>

Make sure we don't leak peripheral/gpio resources when an error occurs
during setup, and make sure we don't call kfree() twice on the same
object.  Also add/fix some error messages in the process.

Signed-off-by: Yi Li <[email protected]>
Signed-off-by: Mike Frysinger <[email protected]>
---
 drivers/spi/spi_bfin5xx.c |   33 ++++++++++++++++++++++++++-------
 1 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index a8fc922..0dcc2ca 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -1118,8 +1118,10 @@ static int bfin_spi_setup(struct spi_device *spi)
        chip = spi_get_ctldata(spi);
        if (chip == NULL) {
                chip = kzalloc(sizeof(*chip), GFP_KERNEL);
-               if (!chip)
+               if (!chip) {
+                       dev_err(&spi->dev, "cannot allocate chip data\n");
                        return -ENOMEM;
+               }
 
                chip->enable_dma = 0;
                chip_info = spi->controller_data;
@@ -1210,7 +1212,7 @@ static int bfin_spi_setup(struct spi_device *spi)
                /* register dma irq handler */
                ret = request_dma(drv_data->dma_channel, "BFIN_SPI_DMA");
                if (ret) {
-                       dev_dbg(&spi->dev,
+                       dev_err(&spi->dev,
                                "Unable to request BlackFin SPI DMA channel\n");
                        goto error;
                }
@@ -1219,7 +1221,7 @@ static int bfin_spi_setup(struct spi_device *spi)
                ret = set_dma_callback(drv_data->dma_channel,
                        bfin_spi_dma_irq_handler, drv_data);
                if (ret) {
-                       dev_dbg(&spi->dev, "Unable to set dma callback\n");
+                       dev_err(&spi->dev, "Unable to set dma callback\n");
                        goto error;
                }
                dma_disable_irq(drv_data->dma_channel);
@@ -1229,7 +1231,7 @@ static int bfin_spi_setup(struct spi_device *spi)
                ret = request_irq(drv_data->spi_irq, bfin_spi_pio_irq_handler,
                        IRQF_DISABLED, "BFIN_SPI", drv_data);
                if (ret) {
-                       printk(KERN_NOTICE "Unable to register spi IRQ\n");
+                       dev_err(&spi->dev, "Unable to register spi IRQ\n");
                        goto error;
                }
                drv_data->irq_requested = 1;
@@ -1239,8 +1241,10 @@ static int bfin_spi_setup(struct spi_device *spi)
 
        if (chip->chip_select_num == 0) {
                ret = gpio_request(chip->cs_gpio, spi->modalias);
-               if (ret)
+               if (ret) {
+                       dev_err(&spi->dev, "gpio_request() error\n");
                        goto error;
+               }
                gpio_direction_output(chip->cs_gpio, 1);
        }
 
@@ -1256,8 +1260,10 @@ static int bfin_spi_setup(struct spi_device *spi)
            chip->chip_select_num <= spi->master->num_chipselect) {
                ret = peripheral_request(ssel[spi->master->bus_num]
                                         [chip->chip_select_num-1], 
spi->modalias);
-               if (ret)
+               if (ret) {
+                       dev_err(&spi->dev, "peripheral_request() error\n");
                        goto error;
+               }
        }
 
        bfin_spi_cs_deactive(drv_data, chip);
@@ -1265,10 +1271,21 @@ static int bfin_spi_setup(struct spi_device *spi)
 
  error:
        if (ret) {
-               kfree(chip);
                if (drv_data->dma_requested)
                        free_dma(drv_data->dma_channel);
                drv_data->dma_requested = 0;
+
+               if ((chip->chip_select_num > 0)
+                       && (chip->chip_select_num <= 
spi->master->num_chipselect))
+                       peripheral_free(ssel[spi->master->bus_num]
+                                               [chip->chip_select_num-1]);
+
+               if (chip->chip_select_num == 0)
+                       gpio_free(chip->cs_gpio);
+
+               kfree(chip);
+               /* prevent free 'chip' twice */
+               spi_set_ctldata(spi, NULL);
        }
 
        return ret;
@@ -1294,6 +1311,8 @@ static void bfin_spi_cleanup(struct spi_device *spi)
                gpio_free(chip->cs_gpio);
 
        kfree(chip);
+       /* prevent free 'chip' twice */
+       spi_set_ctldata(spi, NULL);
 }
 
 static inline int bfin_spi_init_queue(struct driver_data *drv_data)
-- 
1.6.5.rc1


------------------------------------------------------------------------------
Come build with us! The BlackBerry&reg; Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9&#45;12, 2009. Register now&#33;
http://p.sf.net/sfu/devconf
_______________________________________________
spi-devel-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spi-devel-general

Reply via email to