mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 18:21:24 +02:00
dmaengine: ste_dma40: turn d40_base phy_chans into a flexible array
Convert the separately-offset phy_chans pointer to a C99 flexible array member at the end of struct d40_base, and switch the allocation to struct_size(). The log_chans and memcpy_chans slots continue to live in the same allocation immediately after phy_chans, indexed via base->log_chans. This removes the hand-rolled pointer fixup that recomputed phy_chans from base + ALIGN(sizeof(struct d40_base), 4). The ALIGN(sizeof(struct d40_base), 4) requirement is met implicitly by the C compiler when using a flexible array member. With struct d40_chan phy_chans[] as the last member, the C standard guarantees sizeof(struct d40_base) includes trailing padding to satisfy the alignment of the flexible array element type (struct d40_chan). Since struct d40_chan contains members like spinlock_t, pointers, and struct dma_chan — all with alignment ≥ 4 — the compiler ensures sizeof(struct d40_base) is already a multiple of _Alignof(struct d40_chan) >= 4. The struct_size() macro then computes sizeof(struct d40_base) + sizeof(struct d40_chan) * num_phy_chans, so phy_chans[0] lands at a properly aligned offset without needing the manual ALIGN. Assisted-by: Claude:Opus-4.7 Signed-off-by: Rosen Penev <rosenp@gmail.com> Reviewed-by: Linus Walleij <linusw@kernel.org> Link: https://patch.msgid.link/20260531020843.594892-1-rosenp@gmail.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
parent
b55bfcc677
commit
cc4fea19da
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user