Skip to content

Commit 339f504

Browse files
Linus Walleijvinodkoul
authored andcommitted
dmaengine: ste_dma40: Use managed resources
This switches the DMA40 driver to use a bunch of managed resources and strip down the errorpath. The result is pretty neat and makes the driver way more readable. Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Link: https://lore.kernel.org/r/20230417-ux500-dma40-cleanup-v3-6-60bfa6785968@linaro.org Signed-off-by: Vinod Koul <vkoul@kernel.org>
1 parent e59d81e commit 339f504

1 file changed

Lines changed: 61 additions & 119 deletions

File tree

drivers/dma/ste_dma40.c

Lines changed: 61 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -554,8 +554,6 @@ struct d40_gen_dmac {
554554
* @virtbase: The virtual base address of the DMA's register.
555555
* @rev: silicon revision detected.
556556
* @clk: Pointer to the DMA clock structure.
557-
* @phy_start: Physical memory start of the DMA registers.
558-
* @phy_size: Size of the DMA register map.
559557
* @irq: The IRQ number.
560558
* @num_memcpy_chans: The number of channels used for memcpy (mem-to-mem
561559
* transfers).
@@ -599,8 +597,6 @@ struct d40_base {
599597
void __iomem *virtbase;
600598
u8 rev:4;
601599
struct clk *clk;
602-
phys_addr_t phy_start;
603-
resource_size_t phy_size;
604600
int irq;
605601
int num_memcpy_chans;
606602
int num_phy_chans;
@@ -3128,65 +3124,58 @@ static int __init d40_phy_res_init(struct d40_base *base)
31283124
return num_phy_chans_avail;
31293125
}
31303126

3127+
/* Called from the registered devm action */
3128+
static void d40_drop_kmem_cache_action(void *d)
3129+
{
3130+
struct kmem_cache *desc_slab = d;
3131+
3132+
kmem_cache_destroy(desc_slab);
3133+
}
3134+
31313135
static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev)
31323136
{
31333137
struct stedma40_platform_data *plat_data = dev_get_platdata(&pdev->dev);
31343138
struct device *dev = &pdev->dev;
31353139
struct clk *clk;
31363140
void __iomem *virtbase;
3137-
struct resource *res;
31383141
struct d40_base *base;
31393142
int num_log_chans;
31403143
int num_phy_chans;
31413144
int num_memcpy_chans;
3142-
int clk_ret = -EINVAL;
31433145
int i;
31443146
u32 pid;
31453147
u32 cid;
31463148
u8 rev;
3149+
int ret;
31473150

3148-
clk = clk_get(dev, NULL);
3149-
if (IS_ERR(clk)) {
3150-
d40_err(dev, "No matching clock found\n");
3151-
goto check_prepare_enabled;
3152-
}
3153-
3154-
clk_ret = clk_prepare_enable(clk);
3155-
if (clk_ret) {
3156-
d40_err(dev, "Failed to prepare/enable clock\n");
3157-
goto disable_unprepare;
3158-
}
3151+
clk = devm_clk_get_enabled(dev, NULL);
3152+
if (IS_ERR(clk))
3153+
return NULL;
31593154

31603155
/* Get IO for DMAC base address */
3161-
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "base");
3162-
if (!res)
3163-
goto disable_unprepare;
3164-
3165-
if (request_mem_region(res->start, resource_size(res),
3166-
D40_NAME " I/O base") == NULL)
3167-
goto release_region;
3168-
3169-
virtbase = ioremap(res->start, resource_size(res));
3170-
if (!virtbase)
3171-
goto release_region;
3156+
virtbase = devm_platform_ioremap_resource_byname(pdev, "base");
3157+
if (IS_ERR(virtbase)) {
3158+
dev_err(dev, "No IO base defined\n");
3159+
return NULL;
3160+
}
31723161

31733162
/* This is just a regular AMBA PrimeCell ID actually */
31743163
for (pid = 0, i = 0; i < 4; i++)
3175-
pid |= (readl(virtbase + resource_size(res) - 0x20 + 4 * i)
3164+
pid |= (readl(virtbase + SZ_4K - 0x20 + 4 * i)
31763165
& 255) << (i * 8);
31773166
for (cid = 0, i = 0; i < 4; i++)
3178-
cid |= (readl(virtbase + resource_size(res) - 0x10 + 4 * i)
3167+
cid |= (readl(virtbase + SZ_4K - 0x10 + 4 * i)
31793168
& 255) << (i * 8);
31803169

31813170
if (cid != AMBA_CID) {
31823171
d40_err(dev, "Unknown hardware! No PrimeCell ID\n");
3183-
goto unmap_io;
3172+
return NULL;
31843173
}
31853174
if (AMBA_MANF_BITS(pid) != AMBA_VENDOR_ST) {
31863175
d40_err(dev, "Unknown designer! Got %x wanted %x\n",
31873176
AMBA_MANF_BITS(pid),
31883177
AMBA_VENDOR_ST);
3189-
goto unmap_io;
3178+
return NULL;
31903179
}
31913180
/*
31923181
* HW revision:
@@ -3200,7 +3189,7 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev)
32003189
rev = AMBA_REV_BITS(pid);
32013190
if (rev < 2) {
32023191
d40_err(dev, "hardware revision: %d is not supported", rev);
3203-
goto unmap_io;
3192+
return NULL;
32043193
}
32053194

32063195
/* The number of physical channels on this HW */
@@ -3218,23 +3207,22 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev)
32183207
num_log_chans = num_phy_chans * D40_MAX_LOG_CHAN_PER_PHY;
32193208

32203209
dev_info(dev,
3221-
"hardware rev: %d @ %pa with %d physical and %d logical channels\n",
3222-
rev, &res->start, num_phy_chans, num_log_chans);
3210+
"hardware rev: %d with %d physical and %d logical channels\n",
3211+
rev, num_phy_chans, num_log_chans);
32233212

3224-
base = kzalloc(ALIGN(sizeof(struct d40_base), 4) +
3225-
(num_phy_chans + num_log_chans + num_memcpy_chans) *
3226-
sizeof(struct d40_chan), GFP_KERNEL);
3213+
base = devm_kzalloc(dev,
3214+
ALIGN(sizeof(struct d40_base), 4) +
3215+
(num_phy_chans + num_log_chans + num_memcpy_chans) *
3216+
sizeof(struct d40_chan), GFP_KERNEL);
32273217

3228-
if (base == NULL)
3229-
goto unmap_io;
3218+
if (!base)
3219+
return NULL;
32303220

32313221
base->rev = rev;
32323222
base->clk = clk;
32333223
base->num_memcpy_chans = num_memcpy_chans;
32343224
base->num_phy_chans = num_phy_chans;
32353225
base->num_log_chans = num_log_chans;
3236-
base->phy_start = res->start;
3237-
base->phy_size = resource_size(res);
32383226
base->virtbase = virtbase;
32393227
base->plat_data = plat_data;
32403228
base->dev = dev;
@@ -3271,76 +3259,55 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev)
32713259
base->gen_dmac.init_reg_size = ARRAY_SIZE(dma_init_reg_v4a);
32723260
}
32733261

3274-
base->phy_res = kcalloc(num_phy_chans,
3275-
sizeof(*base->phy_res),
3276-
GFP_KERNEL);
3262+
base->phy_res = devm_kcalloc(dev, num_phy_chans,
3263+
sizeof(*base->phy_res),
3264+
GFP_KERNEL);
32773265
if (!base->phy_res)
3278-
goto free_base;
3266+
return NULL;
32793267

3280-
base->lookup_phy_chans = kcalloc(num_phy_chans,
3281-
sizeof(*base->lookup_phy_chans),
3282-
GFP_KERNEL);
3268+
base->lookup_phy_chans = devm_kcalloc(dev, num_phy_chans,
3269+
sizeof(*base->lookup_phy_chans),
3270+
GFP_KERNEL);
32833271
if (!base->lookup_phy_chans)
3284-
goto free_phy_res;
3272+
return NULL;
32853273

3286-
base->lookup_log_chans = kcalloc(num_log_chans,
3287-
sizeof(*base->lookup_log_chans),
3288-
GFP_KERNEL);
3274+
base->lookup_log_chans = devm_kcalloc(dev, num_log_chans,
3275+
sizeof(*base->lookup_log_chans),
3276+
GFP_KERNEL);
32893277
if (!base->lookup_log_chans)
3290-
goto free_phy_chans;
3278+
return NULL;
32913279

3292-
base->reg_val_backup_chan = kmalloc_array(base->num_phy_chans,
3280+
base->reg_val_backup_chan = devm_kmalloc_array(dev, base->num_phy_chans,
32933281
sizeof(d40_backup_regs_chan),
32943282
GFP_KERNEL);
32953283
if (!base->reg_val_backup_chan)
3296-
goto free_log_chans;
3284+
return NULL;
32973285

3298-
base->lcla_pool.alloc_map = kcalloc(num_phy_chans
3286+
base->lcla_pool.alloc_map = devm_kcalloc(dev, num_phy_chans
32993287
* D40_LCLA_LINK_PER_EVENT_GRP,
33003288
sizeof(*base->lcla_pool.alloc_map),
33013289
GFP_KERNEL);
33023290
if (!base->lcla_pool.alloc_map)
3303-
goto free_backup_chan;
3291+
return NULL;
33043292

3305-
base->regs_interrupt = kmalloc_array(base->gen_dmac.il_size,
3293+
base->regs_interrupt = devm_kmalloc_array(dev, base->gen_dmac.il_size,
33063294
sizeof(*base->regs_interrupt),
33073295
GFP_KERNEL);
33083296
if (!base->regs_interrupt)
3309-
goto free_map;
3297+
return NULL;
33103298

33113299
base->desc_slab = kmem_cache_create(D40_NAME, sizeof(struct d40_desc),
33123300
0, SLAB_HWCACHE_ALIGN,
33133301
NULL);
3314-
if (base->desc_slab == NULL)
3315-
goto free_regs;
3302+
if (!base->desc_slab)
3303+
return NULL;
33163304

3305+
ret = devm_add_action_or_reset(dev, d40_drop_kmem_cache_action,
3306+
base->desc_slab);
3307+
if (ret)
3308+
return NULL;
33173309

33183310
return base;
3319-
free_regs:
3320-
kfree(base->regs_interrupt);
3321-
free_map:
3322-
kfree(base->lcla_pool.alloc_map);
3323-
free_backup_chan:
3324-
kfree(base->reg_val_backup_chan);
3325-
free_log_chans:
3326-
kfree(base->lookup_log_chans);
3327-
free_phy_chans:
3328-
kfree(base->lookup_phy_chans);
3329-
free_phy_res:
3330-
kfree(base->phy_res);
3331-
free_base:
3332-
kfree(base);
3333-
unmap_io:
3334-
iounmap(virtbase);
3335-
release_region:
3336-
release_mem_region(res->start, resource_size(res));
3337-
check_prepare_enabled:
3338-
if (!clk_ret)
3339-
disable_unprepare:
3340-
clk_disable_unprepare(clk);
3341-
if (!IS_ERR(clk))
3342-
clk_put(clk);
3343-
return NULL;
33443311
}
33453312

33463313
static void __init d40_hw_init(struct d40_base *base)
@@ -3585,11 +3552,11 @@ static int __init d40_probe(struct platform_device *pdev)
35853552
} else
35863553
writel(base->phy_lcpa, base->virtbase + D40_DREG_LCPA);
35873554

3588-
base->lcpa_base = ioremap(base->phy_lcpa, base->lcpa_size);
3555+
base->lcpa_base = devm_ioremap(dev, base->phy_lcpa, base->lcpa_size);
35893556
if (!base->lcpa_base) {
35903557
ret = -ENOMEM;
35913558
d40_err(dev, "Failed to ioremap LCPA region\n");
3592-
goto release_base;
3559+
goto report_failure;
35933560
}
35943561
/* If lcla has to be located in ESRAM we don't need to allocate */
35953562
if (base->plat_data->use_esram_lcla) {
@@ -3599,14 +3566,14 @@ static int __init d40_probe(struct platform_device *pdev)
35993566
ret = -ENOENT;
36003567
d40_err(dev,
36013568
"No \"lcla_esram\" memory resource\n");
3602-
goto destroy_cache;
3569+
goto report_failure;
36033570
}
3604-
base->lcla_pool.base = ioremap(res->start,
3605-
resource_size(res));
3571+
base->lcla_pool.base = devm_ioremap(dev, res->start,
3572+
resource_size(res));
36063573
if (!base->lcla_pool.base) {
36073574
ret = -ENOMEM;
36083575
d40_err(dev, "Failed to ioremap LCLA region\n");
3609-
goto destroy_cache;
3576+
goto report_failure;
36103577
}
36113578
writel(res->start, base->virtbase + D40_DREG_LCLA);
36123579

@@ -3678,16 +3645,8 @@ static int __init d40_probe(struct platform_device *pdev)
36783645

36793646
dev_info(base->dev, "initialized\n");
36803647
return 0;
3681-
destroy_cache:
3682-
kmem_cache_destroy(base->desc_slab);
3683-
if (base->virtbase)
3684-
iounmap(base->virtbase);
3685-
3686-
if (base->lcla_pool.base && base->plat_data->use_esram_lcla) {
3687-
iounmap(base->lcla_pool.base);
3688-
base->lcla_pool.base = NULL;
3689-
}
36903648

3649+
destroy_cache:
36913650
if (base->lcla_pool.dma_addr)
36923651
dma_unmap_single(base->dev, base->lcla_pool.dma_addr,
36933652
SZ_1K * base->num_phy_chans,
@@ -3699,28 +3658,11 @@ static int __init d40_probe(struct platform_device *pdev)
36993658

37003659
kfree(base->lcla_pool.base_unaligned);
37013660

3702-
if (base->lcpa_base)
3703-
iounmap(base->lcpa_base);
3704-
3705-
release_base:
3706-
if (base->phy_start)
3707-
release_mem_region(base->phy_start,
3708-
base->phy_size);
3709-
if (base->clk) {
3710-
clk_disable_unprepare(base->clk);
3711-
clk_put(base->clk);
3712-
}
3713-
37143661
if (base->lcpa_regulator) {
37153662
regulator_disable(base->lcpa_regulator);
37163663
regulator_put(base->lcpa_regulator);
37173664
}
37183665

3719-
kfree(base->lcla_pool.alloc_map);
3720-
kfree(base->lookup_log_chans);
3721-
kfree(base->lookup_phy_chans);
3722-
kfree(base->phy_res);
3723-
kfree(base);
37243666
report_failure:
37253667
d40_err(dev, "probe failed\n");
37263668
return ret;

0 commit comments

Comments
 (0)