All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] Blackfin SPI: fix resources leakage
@ 2009-06-02  7:06 Mike Frysinger
       [not found] ` <1243926369-29953-1-git-send-email-vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
  0 siblings, 1 reply; 3+ messages in thread
From: Mike Frysinger @ 2009-06-02  7:06 UTC (permalink / raw)
  To: David Brownell, spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: uclinux-dist-devel-ZG0+EudsQA8dtHy/vicBwGD2FQJk+8+b, Daniel Mack

From: Daniel Mack <daniel-rDUAYElUppE@public.gmane.org>

Re-order setup() a bit so we don't leak memory/dma/gpio resources upon
errors.

Signed-off-by: Daniel Mack <daniel-rDUAYElUppE@public.gmane.org>
Signed-off-by: Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
Signed-off-by: Bryan Wu <cooloney-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
 drivers/spi/spi_bfin5xx.c |  101 +++++++++++++++++++++++++--------------------
 1 files changed, 56 insertions(+), 45 deletions(-)

diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index f014cc2..3277210 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -1005,15 +1005,15 @@ 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;
 
 	/* Abort device setup if requested features are not supported */
 	if (spi->mode & ~(SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST)) {
 		dev_err(&spi->dev, "requested mode not fully supported\n");
-		return -EINVAL;
+		goto error;
 	}
 
 	/* Zero (the default) here means 8 bits */
@@ -1021,12 +1021,13 @@ static int bfin_spi_setup(struct spi_device *spi)
 		spi->bits_per_word = 8;
 
 	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);
+		chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 		if (!chip)
 			return -ENOMEM;
 
@@ -1045,7 +1046,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
@@ -1069,26 +1070,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
 	 */
@@ -1096,16 +1077,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;
@@ -1132,9 +1103,37 @@ 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_dbg(&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_dbg(&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)
+			goto error;
+		gpio_direction_output(chip->cs_gpio, 1);
 	}
 
 	dev_dbg(&spi->dev, "setup spi chip %s, width is %d, dma is %d\n",
@@ -1145,14 +1144,26 @@ 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)
+			goto error;
+	}
 
 	bfin_spi_cs_deactive(drv_data, chip);
+	ret = 0;
 
-	return 0;
+ error:
+	if (ret) {
+		kfree(chip);
+		if (drv_data->dma_requested)
+			free_dma(drv_data->dma_channel);
+		drv_data->dma_requested = 0;
+	}
+
+	return ret;
 }
 
 /*
-- 
1.6.3.1


------------------------------------------------------------------------------
OpenSolaris 2009.06 is a cutting edge operating system for enterprises 
looking to deploy the next generation of Solaris that includes the latest 
innovations from Sun and the OpenSource community. Download a copy and 
enjoy capabilities such as Networking, Storage and Virtualization. 
Go to: http://p.sf.net/sfu/opensolaris-get

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/3] Blackfin SPI: force sane state at boot
       [not found] ` <1243926369-29953-1-git-send-email-vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
@ 2009-06-02  7:06   ` Mike Frysinger
  2009-06-02  7:06   ` [PATCH 3/3] Blackfin SPI: work around anomaly 05000119 Mike Frysinger
  1 sibling, 0 replies; 3+ messages in thread
From: Mike Frysinger @ 2009-06-02  7:06 UTC (permalink / raw)
  To: David Brownell, spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: uclinux-dist-devel-ZG0+EudsQA8dtHy/vicBwGD2FQJk+8+b, Wolfgang Muees

From: Wolfgang Muees <wolfgang.mues-3FOdemwfcUYPyMaTEpOvjQ@public.gmane.org>

We should make sure the SPI controller is in a sane state in case the
boot loader left it in a crappy state.  Such as DMA pending which causes
interrupts to fire on us.

Signed-off-by: Wolfgang Muees <wolfgang.mues-3FOdemwfcUYPyMaTEpOvjQ@public.gmane.org>
Signed-off-by: Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
---
 drivers/spi/spi_bfin5xx.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index 3277210..660343b 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -1345,6 +1345,12 @@ static int __init bfin_spi_probe(struct platform_device *pdev)
 		goto out_error_queue_alloc;
 	}
 
+	/* Reset SPI registers. If these registers were used by the boot loader,
+	 * the sky may fall on your head if you enable the dma controller.
+	 */
+	write_CTRL(drv_data, 0x0400);
+	write_FLAG(drv_data, 0xFF00);
+
 	/* Register with the SPI framework */
 	platform_set_drvdata(pdev, drv_data);
 	status = spi_register_master(master);
-- 
1.6.3.1


------------------------------------------------------------------------------
OpenSolaris 2009.06 is a cutting edge operating system for enterprises 
looking to deploy the next generation of Solaris that includes the latest 
innovations from Sun and the OpenSource community. Download a copy and 
enjoy capabilities such as Networking, Storage and Virtualization. 
Go to: http://p.sf.net/sfu/opensolaris-get

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 3/3] Blackfin SPI: work around anomaly 05000119
       [not found] ` <1243926369-29953-1-git-send-email-vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
  2009-06-02  7:06   ` [PATCH 2/3] Blackfin SPI: force sane state at boot Mike Frysinger
@ 2009-06-02  7:06   ` Mike Frysinger
  1 sibling, 0 replies; 3+ messages in thread
From: Mike Frysinger @ 2009-06-02  7:06 UTC (permalink / raw)
  To: David Brownell, spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: uclinux-dist-devel-ZG0+EudsQA8dtHy/vicBwGD2FQJk+8+b, Sonic Zhang

From: Sonic Zhang <sonic.zhang-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>

Anomaly 05000119 states that the DMA_RUN bit with peripherals isn't
reliable.  However, the way the driver is currently written (DMA IRQ
callback), we don't need the polling in the first place, so drop it.

Signed-off-by: Sonic Zhang <sonic.zhang-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
---
 drivers/spi/spi_bfin5xx.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index 660343b..b658456 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -539,10 +539,6 @@ static irqreturn_t bfin_spi_dma_irq_handler(int irq, void *dev_id)
 
 	clear_dma_irqstat(drv_data->dma_channel);
 
-	/* Wait for DMA to complete */
-	while (get_dma_curr_irqstat(drv_data->dma_channel) & DMA_RUN)
-		cpu_relax();
-
 	/*
 	 * wait for the last transaction shifted out.  HRM states:
 	 * at this point there may still be data in the SPI DMA FIFO waiting
-- 
1.6.3.1


------------------------------------------------------------------------------
OpenSolaris 2009.06 is a cutting edge operating system for enterprises 
looking to deploy the next generation of Solaris that includes the latest 
innovations from Sun and the OpenSource community. Download a copy and 
enjoy capabilities such as Networking, Storage and Virtualization. 
Go to: http://p.sf.net/sfu/opensolaris-get

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-06-02  7:06 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-02  7:06 [PATCH 1/3] Blackfin SPI: fix resources leakage Mike Frysinger
     [not found] ` <1243926369-29953-1-git-send-email-vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
2009-06-02  7:06   ` [PATCH 2/3] Blackfin SPI: force sane state at boot Mike Frysinger
2009-06-02  7:06   ` [PATCH 3/3] Blackfin SPI: work around anomaly 05000119 Mike Frysinger

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.