summaryrefslogtreecommitdiff
path: root/drivers/dma/ste_dma40.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/ste_dma40.c')
-rw-r--r--drivers/dma/ste_dma40.c14
1 files changed, 8 insertions, 6 deletions
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) {