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 <[email protected]>
---
 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


Reply via email to