From nobody Mon May 25 06:41:06 2026 Received: from mail-pf1-f171.google.com (mail-pf1-f171.google.com [209.85.210.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 39CC12DECA8 for ; Sun, 17 May 2026 10:41:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779014469; cv=none; b=ZX0mBXm9TO1A8zRrXykywfDdt4JKtl5pZ9Uat8KdIi50563pHHgX2vlK8usf5D7J6FS+Bb/2uCj9Pseho/3obl0lL85hA73EJ5yn1FGlQriQlMhjzyDUoeJ1grVxHiV91tEPsTIaizVY9i5dnvRX93MlcOBoixO9OIYvz5MoV10= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779014469; c=relaxed/simple; bh=h3D3ImvJVD6KhyB0VcERM9OQgo6ma0yzOWE/0rlCSBo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:Cc; b=RZOxMTH4bveMFGhM1KD0LnIG2vzErFGJ5LSAY9JuL83hKD9aK/N22wyEbcD5OEK+s327iS9Z+j4q+Q3WAtO1/29wtL7E4VrJvKD0CLapgjKKR03wBr7fEx9xtEjzgFWSMawgNlGtIuE1t6a83Ng7t5jKfY+JLYwXhhSnN6uPQnc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Zi0xJOgY; arc=none smtp.client-ip=209.85.210.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Zi0xJOgY" Received: by mail-pf1-f171.google.com with SMTP id d2e1a72fcca58-8379e010b01so460101b3a.1 for ; Sun, 17 May 2026 03:41:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779014467; x=1779619267; darn=vger.kernel.org; h=cc:to:message-id:content-transfer-encoding:mime-version:subject :date:from:from:to:cc:subject:date:message-id:reply-to; bh=UDuDwKGGWf9UcWAu5URZf49U1RBStWeCP5aE01gKgdk=; b=Zi0xJOgYoJcSE2pozQDad+ZjJBqZZCLFydDowgBqbrQQfr5yogz3KYjH+iMvM3snEE vxxXhEpXvKBPvCAGjigh9bb1e7wRUEcepxBwOUSepzZeBvY4+xOQa04biM+IOOzHHu1r ytcCruFLoMfTMYvVyMY3wzSOAbyPIIzO3t9x31ejtTK83n3lFGpFSC4lr6+8Gi91Jipf 7zUiN7KnqODp22+uDCwhVNVtUzb6oZZOdY0O9uS8lhYJi50U/GAPdzxA0oquDPe6P0IK f+zVNyGLr5XjMhsvjhC9myjsG27puG7b/K2ZfAZl61nlJ+AkX0js/5PGP56oHX9brw9C or9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779014467; x=1779619267; h=cc:to:message-id:content-transfer-encoding:mime-version:subject :date:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=UDuDwKGGWf9UcWAu5URZf49U1RBStWeCP5aE01gKgdk=; b=ANPBiYJ7baAgWURHn+qV48UpqoQsURtZAz0Go1Ypgqi2LHdG209J/gx6zWwKQFjieP YeJ0zJzsWS/EuvmQvSfatk9u3i7Dk2IkunXayW8SX8nSBezsaHAnNLoy0y/kDq13AbVV ZnWlzoq1IStknLJz0NmmNVHunxG8kxaNe/x7AJKEkrQsRI8IAWdxuSAd+lUlEAbqAipo l3gYpDU6JWbtFiII4tqT1qKkBYLCoqkMafjgBTGfc2IktpF9Khr5Rr5oSrBomfK6xlNK 0Gtr3IN+Fqdpn2lEXLe/SltisiEce5WK+DNpHfPqp1Khbpc7K9fOoorCFEx+SxIWRTP9 UcGA== X-Forwarded-Encrypted: i=1; AFNElJ8fA29df7/GQJcrQ27wCWJcSW05acp+RnlbZ1uQZUJYRuGWkWeO5TYcd78YWrk9owW5Pcm3xh7t+OUKwWo=@vger.kernel.org X-Gm-Message-State: AOJu0Yzx8I8kOfWg1uQ07s5NpUbjwgM/OoDotoCVekdVQCOTuUscfPI6 JQ/BzZY60lWpdN4EyZivBRF1AR6b+gyaQ5k8rBX+zYiElsL11GN3tH8x X-Gm-Gg: Acq92OH0SGuMIa+1XwDeM20/lY48HrKO9+OpvUQ62SCp4BsR8ko50k9A9LKSvBn18d3 Uo0SVMkt6WdeQ6I0GTvxMLsWkHVwBb1E3hTmAQ0houQxMC/L0ofBvMI6OewKqqFfqzZUBpFQEKe fzRmmPsvVRyvgvn4TwSXXjEZqKDxFU984ahfA2E9t735kMvtz8UhAPgAJLh2VLeOiDm8sBpbe86 xOEZaLbK6puTrDXLpb94lxA3l8CtdfgMjaXh87is0ZtokjfBE+63bmkW8NtBjZa7p9LQ2GP3UMZ UNulhxXpMa3I1g/DzJ03kUC8HMZZY34qMxcc47m4VkRCrxlz8fS6iZqX4vBTj+cvWVrGz0CkC0I EsluMZiiVqvH9EnWLlurJ3LwoWVPy6+dAjP+q/Derw9a9dYoOIM10FfFsczvHkdpbWvLNcL+q+0 62xnLh6eOnQ8Q49MSU1TcjmCzGQ5+gO4kDZghlotG7sZ7zXrvLM08W1zvAt3O0NK3bmBE2GhhHK +UC0LrH96ShItEeUmiHBorHoMWy X-Received: by 2002:a05:6a00:a203:b0:834:df57:9d36 with SMTP id d2e1a72fcca58-83f33d9de2dmr11177169b3a.25.1779014467267; Sun, 17 May 2026 03:41:07 -0700 (PDT) Received: from junjungu-PC.localdomain ([223.166.246.30]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-83f19664712sm11488415b3a.12.2026.05.17.03.41.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 17 May 2026 03:41:06 -0700 (PDT) From: Felix Gu Date: Sun, 17 May 2026 18:39:54 +0800 Subject: [PATCH v2] spi: atmel: fix DMA channel and bounce buffer leaks Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260517-atmel-v2-1-36c836be6345@gmail.com> X-B4-Tracking: v=1; b=H4sIAPmaCWoC/12Nyw6DIBBFf8XMujRAFJKu+h+NC8BRp/HRAJI2x n8v2F2XJzn33B0CesIAt2oHj4kCrUsGeanAjWYZkFGXGSSXijdCMRNnnJjqlOWi4Wg1QnZfHnt 6n51H++Ow2Se6WMbFGCnE1X/OoySK999MgnGmdN3bWnNtenUfZkPT1a0ztMdxfAFF+J8DrAAAA A== X-Change-ID: 20260516-atmel-6d6b0150eb7e To: Ryan Wanner , Mark Brown , Nicolas Ferre , Alexandre Belloni , Claudiu Beznea , Radu Pirea , Richard Genoud , Wenyou Yang Cc: linux-spi@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Mark Brown , Felix Gu X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1779014463; l=6687; i=ustc.gu@gmail.com; h=from:subject:message-id; bh=h3D3ImvJVD6KhyB0VcERM9OQgo6ma0yzOWE/0rlCSBo=; b=0qKY9HBnhgMtap3+OWCRR3mUZrdhTKmDNnlawg6EwGL7t8sxY9470XxmzVCJ68Q6pbvjNTHZL 1AUald4HO4HCINme2x8kCpvSdZ39/kPGz0j4q/bsnNGoQO5DbmO+TJn X-Developer-Key: i=ustc.gu@gmail.com; a=ed25519; pk=fjUXwmjchVN7Ja6KGP55IXOzFeCl9edaHoQIEUA+/hw= The original code set use_dma to false when dma_alloc_coherent() for bounce buffers failed, but DMA channels acquired earlier via atmel_spi_configure_dma() were never freed. When devm_request_irq() or clk_prepare_enable() failed later in probe, the driver also did not release DMA channels or bounce buffers already allocated. And in the following error path, the driver released DMA channels but did not free the bounce buffers. Fix by moving bounce buffer allocation into atmel_spi_configure_dma() and switching both DMA channels and bounce buffers to their devm- managed variants. Any allocation failure in the DMA configuration path now correctly rolls back through devres cleanup, and thenow-unnecessary atmel_spi_release_dma() function is removed. Fixes: a9889ed62d06 ("spi: atmel: Implements transfers with bounce buffer") Signed-off-by: Felix Gu --- Changes in v2: - Switch to devm-managed variants to fix Claudiu Beznea's comment. - Link to v1: https://patch.msgid.link/20260516-atmel-v1-0-674fb4707af6@gma= il.com To: Ryan Wanner To: Mark Brown To: Nicolas Ferre To: Alexandre Belloni To: Claudiu Beznea To: Radu Pirea Cc: linux-spi@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org --- drivers/spi/spi-atmel.c | 94 ++++++++++++++-------------------------------= ---- 1 file changed, 27 insertions(+), 67 deletions(-) diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 25aa294631c8..23022665c3a4 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -565,14 +565,15 @@ static int atmel_spi_configure_dma(struct spi_control= ler *host, struct device *dev =3D &as->pdev->dev; int err; =20 - host->dma_tx =3D dma_request_chan(dev, "tx"); + host->dma_tx =3D devm_dma_request_chan(dev, "tx"); if (IS_ERR(host->dma_tx)) { err =3D PTR_ERR(host->dma_tx); dev_dbg(dev, "No TX DMA channel, DMA is disabled\n"); - goto error_clear; + host->dma_tx =3D NULL; + return err; } =20 - host->dma_rx =3D dma_request_chan(dev, "rx"); + host->dma_rx =3D devm_dma_request_chan(dev, "rx"); if (IS_ERR(host->dma_rx)) { err =3D PTR_ERR(host->dma_rx); /* @@ -580,12 +581,27 @@ static int atmel_spi_configure_dma(struct spi_control= ler *host, * requested tx channel. */ dev_dbg(dev, "No RX DMA channel, DMA is disabled\n"); - goto error; + host->dma_rx =3D NULL; + return err; } =20 err =3D atmel_spi_dma_slave_config(as, 8); if (err) - goto error; + return err; + + if (IS_ENABLED(CONFIG_SOC_SAM_V4_V5)) { + as->addr_tx_bbuf =3D dmam_alloc_coherent(dev, SPI_MAX_DMA_XFER, + &as->dma_addr_tx_bbuf, + GFP_KERNEL | GFP_DMA); + if (!as->addr_tx_bbuf) + return -ENOMEM; + + as->addr_rx_bbuf =3D dmam_alloc_coherent(dev, SPI_MAX_DMA_XFER, + &as->dma_addr_rx_bbuf, + GFP_KERNEL | GFP_DMA); + if (!as->addr_rx_bbuf) + return -ENOMEM; + } =20 dev_info(&as->pdev->dev, "Using %s (tx) and %s (rx) for DMA transfers\n", @@ -593,14 +609,7 @@ static int atmel_spi_configure_dma(struct spi_controll= er *host, dma_chan_name(host->dma_rx)); =20 return 0; -error: - if (!IS_ERR(host->dma_rx)) - dma_release_channel(host->dma_rx); - if (!IS_ERR(host->dma_tx)) - dma_release_channel(host->dma_tx); -error_clear: - host->dma_tx =3D host->dma_rx =3D NULL; - return err; + } =20 static void atmel_spi_stop_dma(struct spi_controller *host) @@ -611,18 +620,6 @@ static void atmel_spi_stop_dma(struct spi_controller *= host) dmaengine_terminate_all(host->dma_tx); } =20 -static void atmel_spi_release_dma(struct spi_controller *host) -{ - if (host->dma_rx) { - dma_release_channel(host->dma_rx); - host->dma_rx =3D NULL; - } - if (host->dma_tx) { - dma_release_channel(host->dma_tx); - host->dma_tx =3D NULL; - } -} - /* This function is called by the DMA driver from tasklet context */ static void dma_callback(void *data) { @@ -1581,30 +1578,6 @@ static int atmel_spi_probe(struct platform_device *p= dev) as->use_pdc =3D true; } =20 - if (IS_ENABLED(CONFIG_SOC_SAM_V4_V5)) { - as->addr_rx_bbuf =3D dma_alloc_coherent(&pdev->dev, - SPI_MAX_DMA_XFER, - &as->dma_addr_rx_bbuf, - GFP_KERNEL | GFP_DMA); - if (!as->addr_rx_bbuf) { - as->use_dma =3D false; - } else { - as->addr_tx_bbuf =3D dma_alloc_coherent(&pdev->dev, - SPI_MAX_DMA_XFER, - &as->dma_addr_tx_bbuf, - GFP_KERNEL | GFP_DMA); - if (!as->addr_tx_bbuf) { - as->use_dma =3D false; - dma_free_coherent(&pdev->dev, SPI_MAX_DMA_XFER, - as->addr_rx_bbuf, - as->dma_addr_rx_bbuf); - } - } - if (!as->use_dma) - dev_info(host->dev.parent, - " can not allocate dma coherent memory\n"); - } - if (as->caps.has_dma_support && !as->use_dma) dev_info(&pdev->dev, "Atmel SPI Controller using PIO only\n"); =20 @@ -1652,7 +1625,7 @@ static int atmel_spi_probe(struct platform_device *pd= ev) =20 ret =3D spi_register_controller(host); if (ret) - goto out_free_dma; + goto out_disable_rpm; =20 /* go! */ dev_info(&pdev->dev, "Atmel SPI Controller version 0x%x at 0x%08lx (irq %= d)\n", @@ -1661,16 +1634,13 @@ static int atmel_spi_probe(struct platform_device *= pdev) =20 return 0; =20 -out_free_dma: +out_disable_rpm: pm_runtime_disable(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); - - if (as->use_dma) - atmel_spi_release_dma(host); - spi_writel(as, CR, SPI_BIT(SWRST)); spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ - clk_disable_unprepare(as->gclk); + if (as->gclk) + clk_disable_unprepare(as->gclk); out_disable_clk: clk_disable_unprepare(clk); =20 @@ -1687,18 +1657,8 @@ static void atmel_spi_remove(struct platform_device = *pdev) spi_unregister_controller(host); =20 /* reset the hardware and block queue progress */ - if (as->use_dma) { + if (as->use_dma) atmel_spi_stop_dma(host); - atmel_spi_release_dma(host); - if (IS_ENABLED(CONFIG_SOC_SAM_V4_V5)) { - dma_free_coherent(&pdev->dev, SPI_MAX_DMA_XFER, - as->addr_tx_bbuf, - as->dma_addr_tx_bbuf); - dma_free_coherent(&pdev->dev, SPI_MAX_DMA_XFER, - as->addr_rx_bbuf, - as->dma_addr_rx_bbuf); - } - } =20 spin_lock_irq(&as->lock); spi_writel(as, CR, SPI_BIT(SWRST)); --- base-commit: e98d21c170b01ddef366f023bbfcf6b31509fa83 change-id: 20260516-atmel-6d6b0150eb7e Best regards, -- =20 Felix Gu