[PATCH] dmaengine: st_fdma: simplify allocation
From: Rosen Penev
Date: Mon Mar 30 2026 - 17:18:47 EST
Use a flexible array member to combine kzalloc and kcalloc to a single
allocation.
Add __counted_by for extra runtime analysis. Assign counting variable
after allocation as required by __counted_by.
Signed-off-by: Rosen Penev <rosenp@xxxxxxxxx>
---
drivers/dma/st_fdma.c | 27 ++++++++-------------------
drivers/dma/st_fdma.h | 4 ++--
2 files changed, 10 insertions(+), 21 deletions(-)
diff --git a/drivers/dma/st_fdma.c b/drivers/dma/st_fdma.c
index d9547017f3bd..3ec0d6731b8d 100644
--- a/drivers/dma/st_fdma.c
+++ b/drivers/dma/st_fdma.c
@@ -710,16 +710,6 @@ static const struct of_device_id st_fdma_match[] = {
};
MODULE_DEVICE_TABLE(of, st_fdma_match);
-static int st_fdma_parse_dt(struct platform_device *pdev,
- const struct st_fdma_driverdata *drvdata,
- struct st_fdma_dev *fdev)
-{
- snprintf(fdev->fw_name, FW_NAME_SIZE, "fdma_%s_%d.elf",
- drvdata->name, drvdata->id);
-
- return of_property_read_u32(pdev->dev.of_node, "dma-channels",
- &fdev->nr_channels);
-}
#define FDMA_DMA_BUSWIDTHS (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
BIT(DMA_SLAVE_BUSWIDTH_3_BYTES) | \
@@ -742,27 +732,26 @@ static int st_fdma_probe(struct platform_device *pdev)
struct st_fdma_dev *fdev;
struct device_node *np = pdev->dev.of_node;
const struct st_fdma_driverdata *drvdata;
+ u32 nr_channels;
int ret, i;
drvdata = device_get_match_data(&pdev->dev);
- fdev = devm_kzalloc(&pdev->dev, sizeof(*fdev), GFP_KERNEL);
- if (!fdev)
- return -ENOMEM;
-
- ret = st_fdma_parse_dt(pdev, drvdata, fdev);
+ ret = of_property_read_u32(pdev->dev.of_node, "dma-channels", &nr_channels);
if (ret) {
dev_err(&pdev->dev, "unable to find platform data\n");
- goto err;
+ return ret;
}
- fdev->chans = devm_kcalloc(&pdev->dev, fdev->nr_channels,
- sizeof(struct st_fdma_chan), GFP_KERNEL);
- if (!fdev->chans)
+ fdev = devm_kzalloc(&pdev->dev, struct_size(fdev, chans, nr_channels), GFP_KERNEL);
+ if (!fdev)
return -ENOMEM;
+ fdev->nr_channels = nr_channels;
fdev->dev = &pdev->dev;
fdev->drvdata = drvdata;
+ snprintf(fdev->fw_name, FW_NAME_SIZE, "fdma_%s_%d.elf", drvdata->name, drvdata->id);
+
platform_set_drvdata(pdev, fdev);
fdev->irq = platform_get_irq(pdev, 0);
diff --git a/drivers/dma/st_fdma.h b/drivers/dma/st_fdma.h
index f1e746f7bc7d..27ded555879f 100644
--- a/drivers/dma/st_fdma.h
+++ b/drivers/dma/st_fdma.h
@@ -136,13 +136,13 @@ struct st_fdma_dev {
int irq;
- struct st_fdma_chan *chans;
-
spinlock_t dreq_lock;
unsigned long dreq_mask;
u32 nr_channels;
char fw_name[FW_NAME_SIZE];
+
+ struct st_fdma_chan chans[] __counted_by(nr_channels);
};
/* Peripheral Registers*/
--
2.53.0