Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Linus Walleij and committed by
Vinod Koul
339f5041 e59d81e9

+61 -119
+61 -119
drivers/dma/ste_dma40.c
··· 554 554 * @virtbase: The virtual base address of the DMA's register. 555 555 * @rev: silicon revision detected. 556 556 * @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. 559 557 * @irq: The IRQ number. 560 558 * @num_memcpy_chans: The number of channels used for memcpy (mem-to-mem 561 559 * transfers). ··· 597 599 void __iomem *virtbase; 598 600 u8 rev:4; 599 601 struct clk *clk; 600 - phys_addr_t phy_start; 601 - resource_size_t phy_size; 602 602 int irq; 603 603 int num_memcpy_chans; 604 604 int num_phy_chans; ··· 3124 3128 return num_phy_chans_avail; 3125 3129 } 3126 3130 3131 + /* Called from the registered devm action */ 3132 + static void d40_drop_kmem_cache_action(void *d) 3133 + { 3134 + struct kmem_cache *desc_slab = d; 3135 + 3136 + kmem_cache_destroy(desc_slab); 3137 + } 3138 + 3127 3139 static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) 3128 3140 { 3129 3141 struct stedma40_platform_data *plat_data = dev_get_platdata(&pdev->dev); 3130 3142 struct device *dev = &pdev->dev; 3131 3143 struct clk *clk; 3132 3144 void __iomem *virtbase; 3133 - struct resource *res; 3134 3145 struct d40_base *base; 3135 3146 int num_log_chans; 3136 3147 int num_phy_chans; 3137 3148 int num_memcpy_chans; 3138 - int clk_ret = -EINVAL; 3139 3149 int i; 3140 3150 u32 pid; 3141 3151 u32 cid; 3142 3152 u8 rev; 3153 + int ret; 3143 3154 3144 - clk = clk_get(dev, NULL); 3145 - if (IS_ERR(clk)) { 3146 - d40_err(dev, "No matching clock found\n"); 3147 - goto check_prepare_enabled; 3148 - } 3149 - 3150 - clk_ret = clk_prepare_enable(clk); 3151 - if (clk_ret) { 3152 - d40_err(dev, "Failed to prepare/enable clock\n"); 3153 - goto disable_unprepare; 3154 - } 3155 + clk = devm_clk_get_enabled(dev, NULL); 3156 + if (IS_ERR(clk)) 3157 + return NULL; 3155 3158 3156 3159 /* Get IO for DMAC base address */ 3157 - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "base"); 3158 - if (!res) 3159 - goto disable_unprepare; 3160 - 3161 - if (request_mem_region(res->start, resource_size(res), 3162 - D40_NAME " I/O base") == NULL) 3163 - goto release_region; 3164 - 3165 - virtbase = ioremap(res->start, resource_size(res)); 3166 - if (!virtbase) 3167 - goto release_region; 3160 + virtbase = devm_platform_ioremap_resource_byname(pdev, "base"); 3161 + if (IS_ERR(virtbase)) { 3162 + dev_err(dev, "No IO base defined\n"); 3163 + return NULL; 3164 + } 3168 3165 3169 3166 /* This is just a regular AMBA PrimeCell ID actually */ 3170 3167 for (pid = 0, i = 0; i < 4; i++) 3171 - pid |= (readl(virtbase + resource_size(res) - 0x20 + 4 * i) 3168 + pid |= (readl(virtbase + SZ_4K - 0x20 + 4 * i) 3172 3169 & 255) << (i * 8); 3173 3170 for (cid = 0, i = 0; i < 4; i++) 3174 - cid |= (readl(virtbase + resource_size(res) - 0x10 + 4 * i) 3171 + cid |= (readl(virtbase + SZ_4K - 0x10 + 4 * i) 3175 3172 & 255) << (i * 8); 3176 3173 3177 3174 if (cid != AMBA_CID) { 3178 3175 d40_err(dev, "Unknown hardware! No PrimeCell ID\n"); 3179 - goto unmap_io; 3176 + return NULL; 3180 3177 } 3181 3178 if (AMBA_MANF_BITS(pid) != AMBA_VENDOR_ST) { 3182 3179 d40_err(dev, "Unknown designer! Got %x wanted %x\n", 3183 3180 AMBA_MANF_BITS(pid), 3184 3181 AMBA_VENDOR_ST); 3185 - goto unmap_io; 3182 + return NULL; 3186 3183 } 3187 3184 /* 3188 3185 * HW revision: ··· 3189 3200 rev = AMBA_REV_BITS(pid); 3190 3201 if (rev < 2) { 3191 3202 d40_err(dev, "hardware revision: %d is not supported", rev); 3192 - goto unmap_io; 3203 + return NULL; 3193 3204 } 3194 3205 3195 3206 /* The number of physical channels on this HW */ ··· 3207 3218 num_log_chans = num_phy_chans * D40_MAX_LOG_CHAN_PER_PHY; 3208 3219 3209 3220 dev_info(dev, 3210 - "hardware rev: %d @ %pa with %d physical and %d logical channels\n", 3211 - rev, &res->start, num_phy_chans, num_log_chans); 3221 + "hardware rev: %d with %d physical and %d logical channels\n", 3222 + rev, num_phy_chans, num_log_chans); 3212 3223 3213 - base = kzalloc(ALIGN(sizeof(struct d40_base), 4) + 3214 - (num_phy_chans + num_log_chans + num_memcpy_chans) * 3215 - sizeof(struct d40_chan), GFP_KERNEL); 3224 + base = devm_kzalloc(dev, 3225 + ALIGN(sizeof(struct d40_base), 4) + 3226 + (num_phy_chans + num_log_chans + num_memcpy_chans) * 3227 + sizeof(struct d40_chan), GFP_KERNEL); 3216 3228 3217 - if (base == NULL) 3218 - goto unmap_io; 3229 + if (!base) 3230 + return NULL; 3219 3231 3220 3232 base->rev = rev; 3221 3233 base->clk = clk; 3222 3234 base->num_memcpy_chans = num_memcpy_chans; 3223 3235 base->num_phy_chans = num_phy_chans; 3224 3236 base->num_log_chans = num_log_chans; 3225 - base->phy_start = res->start; 3226 - base->phy_size = resource_size(res); 3227 3237 base->virtbase = virtbase; 3228 3238 base->plat_data = plat_data; 3229 3239 base->dev = dev; ··· 3259 3271 base->gen_dmac.init_reg_size = ARRAY_SIZE(dma_init_reg_v4a); 3260 3272 } 3261 3273 3262 - base->phy_res = kcalloc(num_phy_chans, 3263 - sizeof(*base->phy_res), 3264 - GFP_KERNEL); 3274 + base->phy_res = devm_kcalloc(dev, num_phy_chans, 3275 + sizeof(*base->phy_res), 3276 + GFP_KERNEL); 3265 3277 if (!base->phy_res) 3266 - goto free_base; 3278 + return NULL; 3267 3279 3268 - base->lookup_phy_chans = kcalloc(num_phy_chans, 3269 - sizeof(*base->lookup_phy_chans), 3270 - GFP_KERNEL); 3280 + base->lookup_phy_chans = devm_kcalloc(dev, num_phy_chans, 3281 + sizeof(*base->lookup_phy_chans), 3282 + GFP_KERNEL); 3271 3283 if (!base->lookup_phy_chans) 3272 - goto free_phy_res; 3284 + return NULL; 3273 3285 3274 - base->lookup_log_chans = kcalloc(num_log_chans, 3275 - sizeof(*base->lookup_log_chans), 3276 - GFP_KERNEL); 3286 + base->lookup_log_chans = devm_kcalloc(dev, num_log_chans, 3287 + sizeof(*base->lookup_log_chans), 3288 + GFP_KERNEL); 3277 3289 if (!base->lookup_log_chans) 3278 - goto free_phy_chans; 3290 + return NULL; 3279 3291 3280 - base->reg_val_backup_chan = kmalloc_array(base->num_phy_chans, 3292 + base->reg_val_backup_chan = devm_kmalloc_array(dev, base->num_phy_chans, 3281 3293 sizeof(d40_backup_regs_chan), 3282 3294 GFP_KERNEL); 3283 3295 if (!base->reg_val_backup_chan) 3284 - goto free_log_chans; 3296 + return NULL; 3285 3297 3286 - base->lcla_pool.alloc_map = kcalloc(num_phy_chans 3298 + base->lcla_pool.alloc_map = devm_kcalloc(dev, num_phy_chans 3287 3299 * D40_LCLA_LINK_PER_EVENT_GRP, 3288 3300 sizeof(*base->lcla_pool.alloc_map), 3289 3301 GFP_KERNEL); 3290 3302 if (!base->lcla_pool.alloc_map) 3291 - goto free_backup_chan; 3303 + return NULL; 3292 3304 3293 - base->regs_interrupt = kmalloc_array(base->gen_dmac.il_size, 3305 + base->regs_interrupt = devm_kmalloc_array(dev, base->gen_dmac.il_size, 3294 3306 sizeof(*base->regs_interrupt), 3295 3307 GFP_KERNEL); 3296 3308 if (!base->regs_interrupt) 3297 - goto free_map; 3309 + return NULL; 3298 3310 3299 3311 base->desc_slab = kmem_cache_create(D40_NAME, sizeof(struct d40_desc), 3300 3312 0, SLAB_HWCACHE_ALIGN, 3301 3313 NULL); 3302 - if (base->desc_slab == NULL) 3303 - goto free_regs; 3314 + if (!base->desc_slab) 3315 + return NULL; 3304 3316 3317 + ret = devm_add_action_or_reset(dev, d40_drop_kmem_cache_action, 3318 + base->desc_slab); 3319 + if (ret) 3320 + return NULL; 3305 3321 3306 3322 return base; 3307 - free_regs: 3308 - kfree(base->regs_interrupt); 3309 - free_map: 3310 - kfree(base->lcla_pool.alloc_map); 3311 - free_backup_chan: 3312 - kfree(base->reg_val_backup_chan); 3313 - free_log_chans: 3314 - kfree(base->lookup_log_chans); 3315 - free_phy_chans: 3316 - kfree(base->lookup_phy_chans); 3317 - free_phy_res: 3318 - kfree(base->phy_res); 3319 - free_base: 3320 - kfree(base); 3321 - unmap_io: 3322 - iounmap(virtbase); 3323 - release_region: 3324 - release_mem_region(res->start, resource_size(res)); 3325 - check_prepare_enabled: 3326 - if (!clk_ret) 3327 - disable_unprepare: 3328 - clk_disable_unprepare(clk); 3329 - if (!IS_ERR(clk)) 3330 - clk_put(clk); 3331 - return NULL; 3332 3323 } 3333 3324 3334 3325 static void __init d40_hw_init(struct d40_base *base) ··· 3552 3585 } else 3553 3586 writel(base->phy_lcpa, base->virtbase + D40_DREG_LCPA); 3554 3587 3555 - base->lcpa_base = ioremap(base->phy_lcpa, base->lcpa_size); 3588 + base->lcpa_base = devm_ioremap(dev, base->phy_lcpa, base->lcpa_size); 3556 3589 if (!base->lcpa_base) { 3557 3590 ret = -ENOMEM; 3558 3591 d40_err(dev, "Failed to ioremap LCPA region\n"); 3559 - goto release_base; 3592 + goto report_failure; 3560 3593 } 3561 3594 /* If lcla has to be located in ESRAM we don't need to allocate */ 3562 3595 if (base->plat_data->use_esram_lcla) { ··· 3566 3599 ret = -ENOENT; 3567 3600 d40_err(dev, 3568 3601 "No \"lcla_esram\" memory resource\n"); 3569 - goto destroy_cache; 3602 + goto report_failure; 3570 3603 } 3571 - base->lcla_pool.base = ioremap(res->start, 3572 - resource_size(res)); 3604 + base->lcla_pool.base = devm_ioremap(dev, res->start, 3605 + resource_size(res)); 3573 3606 if (!base->lcla_pool.base) { 3574 3607 ret = -ENOMEM; 3575 3608 d40_err(dev, "Failed to ioremap LCLA region\n"); 3576 - goto destroy_cache; 3609 + goto report_failure; 3577 3610 } 3578 3611 writel(res->start, base->virtbase + D40_DREG_LCLA); 3579 3612 ··· 3645 3678 3646 3679 dev_info(base->dev, "initialized\n"); 3647 3680 return 0; 3681 + 3648 3682 destroy_cache: 3649 - kmem_cache_destroy(base->desc_slab); 3650 - if (base->virtbase) 3651 - iounmap(base->virtbase); 3652 - 3653 - if (base->lcla_pool.base && base->plat_data->use_esram_lcla) { 3654 - iounmap(base->lcla_pool.base); 3655 - base->lcla_pool.base = NULL; 3656 - } 3657 - 3658 3683 if (base->lcla_pool.dma_addr) 3659 3684 dma_unmap_single(base->dev, base->lcla_pool.dma_addr, 3660 3685 SZ_1K * base->num_phy_chans, ··· 3658 3699 3659 3700 kfree(base->lcla_pool.base_unaligned); 3660 3701 3661 - if (base->lcpa_base) 3662 - iounmap(base->lcpa_base); 3663 - 3664 - release_base: 3665 - if (base->phy_start) 3666 - release_mem_region(base->phy_start, 3667 - base->phy_size); 3668 - if (base->clk) { 3669 - clk_disable_unprepare(base->clk); 3670 - clk_put(base->clk); 3671 - } 3672 - 3673 3702 if (base->lcpa_regulator) { 3674 3703 regulator_disable(base->lcpa_regulator); 3675 3704 regulator_put(base->lcpa_regulator); 3676 3705 } 3677 3706 3678 - kfree(base->lcla_pool.alloc_map); 3679 - kfree(base->lookup_log_chans); 3680 - kfree(base->lookup_phy_chans); 3681 - kfree(base->phy_res); 3682 - kfree(base); 3683 3707 report_failure: 3684 3708 d40_err(dev, "probe failed\n"); 3685 3709 return ret;