Simplifies allocations by using a flexible array member in this struct.

Remove idma64_alloc_desc. It now offers no readability advantages in
this single usage.

Add __counted_by to get extra runtime analysis.

Apply the exact same treatment to struct idma64_dma and devm_kzalloc.

Signed-off-by: Rosen Penev <[email protected]>
---
 drivers/dma/idma64.c | 30 ++++--------------------------
 drivers/dma/idma64.h |  4 ++--
 2 files changed, 6 insertions(+), 28 deletions(-)

diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c
index 5fcd1befc92d..cf0399251ea9 100644
--- a/drivers/dma/idma64.c
+++ b/drivers/dma/idma64.c
@@ -192,23 +192,6 @@ static irqreturn_t idma64_irq(int irq, void *dev)
 
 /* ---------------------------------------------------------------------- */
 
-static struct idma64_desc *idma64_alloc_desc(unsigned int ndesc)
-{
-       struct idma64_desc *desc;
-
-       desc = kzalloc_obj(*desc, GFP_NOWAIT);
-       if (!desc)
-               return NULL;
-
-       desc->hw = kzalloc_objs(*desc->hw, ndesc, GFP_NOWAIT);
-       if (!desc->hw) {
-               kfree(desc);
-               return NULL;
-       }
-
-       return desc;
-}
-
 static void idma64_desc_free(struct idma64_chan *idma64c,
                struct idma64_desc *desc)
 {
@@ -223,7 +206,6 @@ static void idma64_desc_free(struct idma64_chan *idma64c,
                } while (i);
        }
 
-       kfree(desc->hw);
        kfree(desc);
 }
 
@@ -307,10 +289,12 @@ static struct dma_async_tx_descriptor 
*idma64_prep_slave_sg(
        struct scatterlist *sg;
        unsigned int i;
 
-       desc = idma64_alloc_desc(sg_len);
+       desc = kzalloc_flex(*desc, hw, sg_len);
        if (!desc)
                return NULL;
 
+       desc->ndesc = sg_len;
+
        for_each_sg(sgl, sg, sg_len, i) {
                struct idma64_hw_desc *hw = &desc->hw[i];
 
@@ -326,7 +310,6 @@ static struct dma_async_tx_descriptor *idma64_prep_slave_sg(
                hw->len = sg_dma_len(sg);
        }
 
-       desc->ndesc = sg_len;
        desc->direction = direction;
        desc->status = DMA_IN_PROGRESS;
 
@@ -541,18 +524,13 @@ static int idma64_probe(struct idma64_chip *chip)
        unsigned short i;
        int ret;
 
-       idma64 = devm_kzalloc(chip->dev, sizeof(*idma64), GFP_KERNEL);
+       idma64 = devm_kzalloc(chip->dev, struct_size(idma64, chan, nr_chan), 
GFP_KERNEL);
        if (!idma64)
                return -ENOMEM;
 
        idma64->regs = chip->regs;
        chip->idma64 = idma64;
 
-       idma64->chan = devm_kcalloc(chip->dev, nr_chan, sizeof(*idma64->chan),
-                                   GFP_KERNEL);
-       if (!idma64->chan)
-               return -ENOMEM;
-
        idma64->all_chan_mask = (1 << nr_chan) - 1;
 
        /* Turn off iDMA controller */
diff --git a/drivers/dma/idma64.h b/drivers/dma/idma64.h
index d013b54356aa..1a67dbb24db5 100644
--- a/drivers/dma/idma64.h
+++ b/drivers/dma/idma64.h
@@ -113,10 +113,10 @@ struct idma64_hw_desc {
 struct idma64_desc {
        struct virt_dma_desc vdesc;
        enum dma_transfer_direction direction;
-       struct idma64_hw_desc *hw;
        unsigned int ndesc;
        size_t length;
        enum dma_status status;
+       struct idma64_hw_desc hw[] __counted_by(ndesc);
 };
 
 static inline struct idma64_desc *to_idma64_desc(struct virt_dma_desc *vdesc)
@@ -187,7 +187,7 @@ struct idma64 {
 
        /* channels */
        unsigned short all_chan_mask;
-       struct idma64_chan *chan;
+       struct idma64_chan chan[];
 };
 
 static inline struct idma64 *to_idma64(struct dma_device *ddev)
-- 
2.53.0


Reply via email to