linux-spi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
To: Mark Brown <broonie@kernel.org>,
	Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	Linus Walleij <linus.walleij@linaro.org>,
	linux-kernel@vger.kernel.org, linux-spi@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
Cc: Daniel Mack <daniel@zonque.org>,
	Haojian Zhuang <haojian.zhuang@gmail.com>,
	Robert Jarzmik <robert.jarzmik@free.fr>
Subject: [PATCH v2 01/11] spi: pxa2xx: Wrap pxa_ssp_request() to be device managed resource
Date: Thu, 30 May 2024 18:09:57 +0300	[thread overview]
Message-ID: <20240530151117.1130792-2-andriy.shevchenko@linux.intel.com> (raw)
In-Reply-To: <20240530151117.1130792-1-andriy.shevchenko@linux.intel.com>

In the error path or remove path the reference counter in PXA SSP driver
may be dropped before the other resources, that were allocated after
bumbing the reference counter. This breaks reversed order of freeing and
might have an undesired side effects. Prevent this from happening by
wrapping pxa_ssp_request() to be device managed resource.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/spi/spi-pxa2xx.c | 50 +++++++++++++++++++++++++---------------
 1 file changed, 32 insertions(+), 18 deletions(-)

diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
index efe76d0c21bb..820a3702447a 100644
--- a/drivers/spi/spi-pxa2xx.c
+++ b/drivers/spi/spi-pxa2xx.c
@@ -1304,6 +1304,27 @@ pxa2xx_spi_init_ssp(struct platform_device *pdev, struct ssp_device *ssp, enum p
 	return 0;
 }
 
+static void pxa2xx_spi_ssp_release(void *ssp)
+{
+	pxa_ssp_free(ssp);
+}
+
+static struct ssp_device *pxa2xx_spi_ssp_request(struct platform_device *pdev)
+{
+	struct ssp_device *ssp;
+	int status;
+
+	ssp = pxa_ssp_request(pdev->id, pdev->name);
+	if (!ssp)
+		return ssp;
+
+	status = devm_add_action_or_reset(&pdev->dev, pxa2xx_spi_ssp_release, ssp);
+	if (status)
+		return ERR_PTR(status);
+
+	return ssp;
+}
+
 static struct pxa2xx_spi_controller *
 pxa2xx_spi_init_pdata(struct platform_device *pdev)
 {
@@ -1331,11 +1352,11 @@ pxa2xx_spi_init_pdata(struct platform_device *pdev)
 
 		type = (enum pxa_ssp_type)value;
 	} else {
-		ssp = pxa_ssp_request(pdev->id, pdev->name);
-		if (ssp) {
+		ssp = pxa2xx_spi_ssp_request(pdev);
+		if (IS_ERR(ssp))
+			return ERR_CAST(ssp);
+		if (ssp)
 			type = ssp->type;
-			pxa_ssp_free(ssp);
-		}
 	}
 
 	/* Validate the SSP type correctness */
@@ -1420,7 +1441,9 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
 	}
 	dev_dbg(dev, "DMA burst size set to %u\n", platform_info->dma_burst_size);
 
-	ssp = pxa_ssp_request(pdev->id, pdev->name);
+	ssp = pxa2xx_spi_ssp_request(pdev);
+	if (IS_ERR(ssp))
+		return PTR_ERR(ssp);
 	if (!ssp)
 		ssp = &platform_info->ssp;
 
@@ -1431,11 +1454,9 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
 		controller = devm_spi_alloc_target(dev, sizeof(*drv_data));
 	else
 		controller = devm_spi_alloc_host(dev, sizeof(*drv_data));
+	if (!controller)
+		return dev_err_probe(dev, -ENOMEM, "cannot alloc spi_controller\n");
 
-	if (!controller) {
-		status = dev_err_probe(dev, -ENOMEM, "cannot alloc spi_controller\n");
-		goto out_error_controller_alloc;
-	}
 	drv_data = spi_controller_get_devdata(controller);
 	drv_data->controller = controller;
 	drv_data->controller_info = platform_info;
@@ -1486,10 +1507,8 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
 
 	status = request_irq(ssp->irq, ssp_int, IRQF_SHARED, dev_name(dev),
 			drv_data);
-	if (status < 0) {
-		dev_err_probe(dev, status, "cannot get IRQ %d\n", ssp->irq);
-		goto out_error_controller_alloc;
-	}
+	if (status < 0)
+		return dev_err_probe(dev, status, "cannot get IRQ %d\n", ssp->irq);
 
 	/* Setup DMA if requested */
 	if (platform_info->enable_dma) {
@@ -1619,8 +1638,6 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
 	pxa2xx_spi_dma_release(drv_data);
 	free_irq(ssp->irq, drv_data);
 
-out_error_controller_alloc:
-	pxa_ssp_free(ssp);
 	return status;
 }
 
@@ -1646,9 +1663,6 @@ static void pxa2xx_spi_remove(struct platform_device *pdev)
 
 	/* Release IRQ */
 	free_irq(ssp->irq, drv_data);
-
-	/* Release SSP */
-	pxa_ssp_free(ssp);
 }
 
 static int pxa2xx_spi_suspend(struct device *dev)
-- 
2.43.0.rc1.1336.g36b5255a03ac


  reply	other threads:[~2024-05-30 15:11 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-30 15:09 [PATCH v2 00/11] spi: pxa2xx: Get rid of an additional layer in PCI driver Andy Shevchenko
2024-05-30 15:09 ` Andy Shevchenko [this message]
2024-05-30 15:09 ` [PATCH v2 02/11] spi: pxa2xx: Reorganize the SSP type retrieval Andy Shevchenko
2024-05-30 15:09 ` [PATCH v2 03/11] spi: pxa2xx: Remove no more needed driver data Andy Shevchenko
2024-05-30 15:10 ` [PATCH v2 04/11] spi: pxa2xx: Remove hard coded number of chip select pins Andy Shevchenko
2024-05-30 15:10 ` [PATCH v2 05/11] spi: pxa2xx: Utilise temporary variable for struct device Andy Shevchenko
2024-05-30 15:10 ` [PATCH v2 06/11] spi: pxa2xx: Print DMA burst size only when DMA is enabled Andy Shevchenko
2024-05-30 15:10 ` [PATCH v2 07/11] spi: pxa2xx: Remove duplicate check Andy Shevchenko
2024-05-30 15:10 ` [PATCH v2 08/11] spi: pxa2xx: Remove superflous check for Intel Atom SoCs Andy Shevchenko
2024-05-30 15:10 ` [PATCH v2 09/11] spi: pxa2xx: Extract pxa2xx_spi_platform_*() callbacks Andy Shevchenko
2024-05-30 15:10 ` [PATCH v2 10/11] spi: pxa2xx: Move platform driver to a separate file Andy Shevchenko
2024-05-30 15:10 ` [PATCH v2 11/11] spi: pxa2xx: Convert PCI driver to use spi-pxa2xx code directly Andy Shevchenko
2024-06-05 21:38 ` [PATCH v2 00/11] spi: pxa2xx: Get rid of an additional layer in PCI driver Mark Brown

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=20240530151117.1130792-2-andriy.shevchenko@linux.intel.com \
    --to=andriy.shevchenko@linux.intel.com \
    --cc=broonie@kernel.org \
    --cc=daniel@zonque.org \
    --cc=haojian.zhuang@gmail.com \
    --cc=linus.walleij@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-spi@vger.kernel.org \
    --cc=robert.jarzmik@free.fr \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).