From: Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
To: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
David Brownell
<dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>,
Grant Likely
<grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
Cc: uclinux-dist-devel-ZG0+EudsQA8dtHy/vicBwGD2FQJk+8+b@public.gmane.org,
Yi Li <yi.li-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>,
Daniel Mack <daniel-rDUAYElUppE@public.gmane.org>
Subject: [PATCH 01/28] Blackfin SPI: fix resources leakage
Date: Sun, 17 Oct 2010 18:59:14 -0400 [thread overview]
Message-ID: <1287356381-31495-2-git-send-email-vapier@gentoo.org> (raw)
In-Reply-To: <1287356381-31495-1-git-send-email-vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
From: Daniel Mack <daniel-rDUAYElUppE@public.gmane.org>
Re-order setup() a bit so we don't leak memory/dma/gpio resources upon
errors. Also make sure we don't call kfree() twice on the same object.
Signed-off-by: Daniel Mack <daniel-rDUAYElUppE@public.gmane.org>
Signed-off-by: Bryan Wu <cooloney-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Yi Li <yi.li-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
---
drivers/spi/spi_bfin5xx.c | 120 ++++++++++++++++++++++++++++-----------------
1 files changed, 75 insertions(+), 45 deletions(-)
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index 10a6dc3..4f20b92 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -1006,20 +1006,24 @@ static u16 ssel[][MAX_SPI_SSEL] = {
/* first setup for new devices */
static int bfin_spi_setup(struct spi_device *spi)
{
- struct bfin5xx_spi_chip *chip_info = NULL;
- struct chip_data *chip;
+ struct bfin5xx_spi_chip *chip_info;
+ struct chip_data *chip = NULL;
struct driver_data *drv_data = spi_master_get_devdata(spi->master);
- int ret;
+ int ret = -EINVAL;
if (spi->bits_per_word != 8 && spi->bits_per_word != 16)
- return -EINVAL;
+ goto error;
/* Only alloc (or use chip_info) on first setup */
+ chip_info = NULL;
chip = spi_get_ctldata(spi);
if (chip == NULL) {
- chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL);
- if (!chip)
- return -ENOMEM;
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+ if (!chip) {
+ dev_err(&spi->dev, "cannot allocate chip data\n");
+ ret = -ENOMEM;
+ goto error;
+ }
chip->enable_dma = 0;
chip_info = spi->controller_data;
@@ -1036,7 +1040,7 @@ static int bfin_spi_setup(struct spi_device *spi)
if (chip_info->ctl_reg & (SPE|MSTR|CPOL|CPHA|LSBF|SIZE)) {
dev_err(&spi->dev, "do not set bits in ctl_reg "
"that the SPI framework manages\n");
- return -EINVAL;
+ goto error;
}
chip->enable_dma = chip_info->enable_dma != 0
@@ -1060,26 +1064,6 @@ static int bfin_spi_setup(struct spi_device *spi)
chip->ctl_reg |= MSTR;
/*
- * if any one SPI chip is registered and wants DMA, request the
- * DMA channel for it
- */
- if (chip->enable_dma && !drv_data->dma_requested) {
- /* register dma irq handler */
- if (request_dma(drv_data->dma_channel, "BFIN_SPI_DMA") < 0) {
- dev_dbg(&spi->dev,
- "Unable to request BlackFin SPI DMA channel\n");
- return -ENODEV;
- }
- if (set_dma_callback(drv_data->dma_channel,
- bfin_spi_dma_irq_handler, drv_data) < 0) {
- dev_dbg(&spi->dev, "Unable to set dma callback\n");
- return -EPERM;
- }
- dma_disable_irq(drv_data->dma_channel);
- drv_data->dma_requested = 1;
- }
-
- /*
* Notice: for blackfin, the speed_hz is the value of register
* SPI_BAUD, not the real baudrate
*/
@@ -1087,16 +1071,6 @@ static int bfin_spi_setup(struct spi_device *spi)
chip->flag = 1 << (spi->chip_select);
chip->chip_select_num = spi->chip_select;
- if (chip->chip_select_num == 0) {
- ret = gpio_request(chip->cs_gpio, spi->modalias);
- if (ret) {
- if (drv_data->dma_requested)
- free_dma(drv_data->dma_channel);
- return ret;
- }
- gpio_direction_output(chip->cs_gpio, 1);
- }
-
switch (chip->bits_per_word) {
case 8:
chip->n_bytes = 1;
@@ -1123,9 +1097,39 @@ static int bfin_spi_setup(struct spi_device *spi)
default:
dev_err(&spi->dev, "%d bits_per_word is not supported\n",
chip->bits_per_word);
- if (chip_info)
- kfree(chip);
- return -ENODEV;
+ goto error;
+ }
+
+ /*
+ * if any one SPI chip is registered and wants DMA, request the
+ * DMA channel for it
+ */
+ if (chip->enable_dma && !drv_data->dma_requested) {
+ /* register dma irq handler */
+ ret = request_dma(drv_data->dma_channel, "BFIN_SPI_DMA");
+ if (ret) {
+ dev_err(&spi->dev,
+ "Unable to request BlackFin SPI DMA channel\n");
+ goto error;
+ }
+ drv_data->dma_requested = 1;
+
+ ret = set_dma_callback(drv_data->dma_channel,
+ bfin_spi_dma_irq_handler, drv_data);
+ if (ret) {
+ dev_err(&spi->dev, "Unable to set dma callback\n");
+ goto error;
+ }
+ dma_disable_irq(drv_data->dma_channel);
+ }
+
+ if (chip->chip_select_num == 0) {
+ ret = gpio_request(chip->cs_gpio, spi->modalias);
+ if (ret) {
+ dev_err(&spi->dev, "gpio_request() error\n");
+ goto pin_error;
+ }
+ gpio_direction_output(chip->cs_gpio, 1);
}
dev_dbg(&spi->dev, "setup spi chip %s, width is %d, dma is %d\n",
@@ -1136,14 +1140,38 @@ static int bfin_spi_setup(struct spi_device *spi)
spi_set_ctldata(spi, chip);
dev_dbg(&spi->dev, "chip select number is %d\n", chip->chip_select_num);
- if ((chip->chip_select_num > 0)
- && (chip->chip_select_num <= spi->master->num_chipselect))
- peripheral_request(ssel[spi->master->bus_num]
- [chip->chip_select_num-1], spi->modalias);
+ if (chip->chip_select_num > 0 &&
+ 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) {
+ dev_err(&spi->dev, "peripheral_request() error\n");
+ goto pin_error;
+ }
+ }
bfin_spi_cs_deactive(drv_data, chip);
return 0;
+
+ pin_error:
+ if (chip->chip_select_num == 0)
+ gpio_free(chip->cs_gpio);
+ else
+ peripheral_free(ssel[spi->master->bus_num]
+ [chip->chip_select_num - 1]);
+ error:
+ if (chip) {
+ if (drv_data->dma_requested)
+ free_dma(drv_data->dma_channel);
+ drv_data->dma_requested = 0;
+
+ kfree(chip);
+ /* prevent free 'chip' twice */
+ spi_set_ctldata(spi, NULL);
+ }
+
+ return ret;
}
/*
@@ -1166,6 +1194,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.7.3.1
next prev parent reply other threads:[~2010-10-17 22:59 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-10-17 22:59 [PATCH 00/28] Blackfin SPI updates for 2.6.36 Mike Frysinger
[not found] ` <1287356381-31495-1-git-send-email-vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
2010-10-17 22:59 ` Mike Frysinger [this message]
2010-10-17 22:59 ` [PATCH 02/28] Blackfin SPI: work around anomaly 05000119 Mike Frysinger
2010-10-17 22:59 ` [PATCH 03/28] Blackfin SPI: force sane master-mode state at boot Mike Frysinger
2010-10-17 22:59 ` [PATCH 04/28] Blackfin SPI: utilize the SPI interrupt in PIO mode Mike Frysinger
2010-10-17 22:59 ` [PATCH 05/28] Blackfin SPI: fix CS handling Mike Frysinger
2010-10-17 22:59 ` [PATCH 06/28] Blackfin SPI: drop custom cs_change_per_word support Mike Frysinger
2010-10-17 22:59 ` [PATCH 07/28] Blackfin SPI: punt useless null read/write funcs Mike Frysinger
2010-10-17 22:59 ` [PATCH 08/28] Blackfin SPI: fix up some unused/misleading comments Mike Frysinger
2010-10-17 22:59 ` [PATCH 09/28] Blackfin SPI: convert queue run state to true/false Mike Frysinger
2010-10-17 22:59 ` [PATCH 10/28] Blackfin SPI: convert read/write/duplex funcs to a dedicated ops structure Mike Frysinger
2010-10-17 22:59 ` [PATCH 11/28] Blackfin SPI: convert struct names to something more logical Mike Frysinger
[not found] ` <1287356381-31495-12-git-send-email-vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
2010-10-18 6:02 ` Grant Likely
[not found] ` <20101018060253.GA19399-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
2010-10-18 6:10 ` Mike Frysinger
[not found] ` <AANLkTimJtoRWL0auw1xHthXbkBc6L2b1ph18WZA+_PdY-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2010-10-18 6:20 ` Grant Likely
[not found] ` <20101018062025.GD19399-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
2010-10-18 6:28 ` Mike Frysinger
[not found] ` <AANLkTi=pBYVLCYVtwd3L=O31O4FxOPwQLJQK5WUkdRS9-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2010-10-18 6:31 ` Grant Likely
2010-10-17 22:59 ` [PATCH 12/28] Blackfin SPI: drop extra memory we don't need Mike Frysinger
2010-10-17 22:59 ` [PATCH 13/28] Blackfin SPI: use the SPI namespaced bit names Mike Frysinger
2010-10-17 22:59 ` [PATCH 14/28] Blackfin: SPI: expand SPI bitmasks Mike Frysinger
[not found] ` <1287356381-31495-15-git-send-email-vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
2010-10-18 6:04 ` Grant Likely
[not found] ` <20101018060416.GB19399-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
2010-10-18 6:11 ` Mike Frysinger
2010-10-17 22:59 ` [PATCH 15/28] Blackfin SPI: redo GPIO CS handling Mike Frysinger
2010-10-17 22:59 ` [PATCH 16/28] Blackfin SPI: save/restore state when suspending/resuming Mike Frysinger
2010-10-17 22:59 ` [PATCH 17/28] Blackfin SPI: sync hardware state before reprogramming everything Mike Frysinger
2010-10-17 22:59 ` [PATCH 18/28] Blackfin SPI: use nosync when disabling the IRQ from the IRQ handler Mike Frysinger
2010-10-17 22:59 ` [PATCH 19/28] Blackfin SPI: push all size checks into the transfer function Mike Frysinger
2010-10-17 22:59 ` [PATCH 20/28] Blackfin SPI: reset ctl_reg bits when setup is run again on a device Mike Frysinger
2010-10-17 22:59 ` [PATCH 21/28] Blackfin SPI: combine duplicate SPI_CTL read/write logic Mike Frysinger
2010-10-17 22:59 ` [PATCH 22/28] Blackfin SPI: use dma_disable_irq_nosync() in irq handler Mike Frysinger
2010-10-17 22:59 ` [PATCH 23/28] Blackfin SPI: reject unsupported SPI modes Mike Frysinger
2010-10-17 22:59 ` [PATCH 24/28] Blackfin SPI: fix typo in comment Mike Frysinger
2010-10-17 22:59 ` [PATCH 25/28] Blackfin SPI: cs should be always low when a new transfer begins Mike Frysinger
2010-10-17 22:59 ` [PATCH 26/28] Blackfin SPI: warn when CS is driven by hardware (CPHA=0) Mike Frysinger
2010-10-17 22:59 ` [PATCH 27/28] Blackfin SPI: check per-transfer bits_per_word Mike Frysinger
2010-10-17 22:59 ` [PATCH 28/28] Blackfin SPI: init early Mike Frysinger
[not found] ` <1287356381-31495-29-git-send-email-vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
2010-10-18 6:12 ` Grant Likely
[not found] ` <20101018061211.GC19399-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
2010-10-18 6:14 ` Mike Frysinger
[not found] ` <AANLkTi=AwuK8-U8+Ezm1JVrvD1Taqwq53EzahA5Ag4Uf-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2010-10-18 6:21 ` Grant Likely
2010-10-18 6:28 ` [PATCH 00/28] Blackfin SPI updates for 2.6.36 Grant Likely
[not found] ` <20101018062834.GG19399-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
2010-10-18 6:34 ` Mike Frysinger
[not found] ` <AANLkTims9Z+XGXMdcAH53OBO=S9aYiszxHczmsTn06Gd-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2010-10-18 6:37 ` Mike Frysinger
[not found] ` <AANLkTim1p0Ukufh1dWGSk8L2yA4xwQzsWmr8EK_AbfLP-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2010-10-18 6:49 ` Grant Likely
2010-10-18 6:49 ` Mike Frysinger
[not found] ` <AANLkTimmVQ0EtkACtXqxO0vkXfN9FoyF9c6OLo3JNPUC-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2010-10-18 7:04 ` Grant Likely
[not found] ` <AANLkTimE33PngPfSBkQDVR7x6H8fMNQ9z3sXNC9KZPWf-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2010-10-18 15:27 ` Grant Likely
2010-10-18 6:46 ` [PATCH 29/28] spi/bfin_spi: namespace local structs Mike Frysinger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1287356381-31495-2-git-send-email-vapier@gentoo.org \
--to=vapier-abrp7r+bbdudnm+yrofe0a@public.gmane.org \
--cc=daniel-rDUAYElUppE@public.gmane.org \
--cc=dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
--cc=grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org \
--cc=spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
--cc=uclinux-dist-devel-ZG0+EudsQA8dtHy/vicBwGD2FQJk+8+b@public.gmane.org \
--cc=yi.li-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.