diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 9b803c0aec25..0d9ffa3e2663 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -602,7 +602,6 @@ struct d40_base { struct dma_device dma_both; struct dma_device dma_slave; struct dma_device dma_memcpy; - struct d40_chan *phy_chans; struct d40_chan *log_chans; struct d40_chan **lookup_log_chans; struct d40_chan **lookup_phy_chans; @@ -621,6 +620,7 @@ struct d40_base { u32 *regs_interrupt; u16 gcc_pwr_off_mask; struct d40_gen_dmac gen_dmac; + struct d40_chan phy_chans[]; }; static struct device *chan2dev(struct d40_chan *d40c) @@ -3128,6 +3128,7 @@ static int __init d40_hw_detect_init(struct platform_device *pdev, struct clk *clk; void __iomem *virtbase; struct d40_base *base; + size_t alloc_size; int num_log_chans; int num_phy_chans; int num_memcpy_chans; @@ -3185,22 +3186,24 @@ static int __init d40_hw_detect_init(struct platform_device *pdev, else num_phy_chans = 4 * (readl(virtbase + D40_DREG_ICFG) & 0x7) + 4; + num_phy_chans = min(num_phy_chans, STEDMA40_MAX_PHYS); + /* The number of channels used for memcpy */ if (plat_data->num_of_memcpy_chans) num_memcpy_chans = plat_data->num_of_memcpy_chans; else num_memcpy_chans = ARRAY_SIZE(dma40_memcpy_channels); + num_memcpy_chans = min(num_memcpy_chans, D40_MEMCPY_MAX_CHANS); num_log_chans = num_phy_chans * D40_MAX_LOG_CHAN_PER_PHY; dev_info(dev, "hardware rev: %d with %d physical and %d logical channels\n", rev, num_phy_chans, num_log_chans); - base = devm_kzalloc(dev, - ALIGN(sizeof(struct d40_base), 4) + - (num_phy_chans + num_log_chans + num_memcpy_chans) * - sizeof(struct d40_chan), GFP_KERNEL); + alloc_size = struct_size(base, phy_chans, num_phy_chans); + alloc_size += sizeof(*base->log_chans) * (num_log_chans + num_memcpy_chans); + base = devm_kzalloc(dev, alloc_size, GFP_KERNEL); if (!base) return -ENOMEM; @@ -3213,7 +3216,6 @@ static int __init d40_hw_detect_init(struct platform_device *pdev, base->virtbase = virtbase; base->plat_data = plat_data; base->dev = dev; - base->phy_chans = ((void *)base) + ALIGN(sizeof(struct d40_base), 4); base->log_chans = &base->phy_chans[num_phy_chans]; if (base->plat_data->num_of_phy_chans == 14) {