diff --git a/drivers/crypto/marvell/cesa/cesa.c b/drivers/crypto/marvell/cesa/cesa.c index 75d8ba23d9a2..4859ad2e86b4 100644 --- a/drivers/crypto/marvell/cesa/cesa.c +++ b/drivers/crypto/marvell/cesa/cesa.c @@ -366,6 +366,8 @@ static int mv_cesa_dev_dma_init(struct mv_cesa_dev *cesa) return 0; } +static void mv_cesa_release_sram(void *data); + static int mv_cesa_get_sram(struct platform_device *pdev, int idx) { struct mv_cesa_dev *cesa = platform_get_drvdata(pdev); @@ -378,11 +380,13 @@ static int mv_cesa_get_sram(struct platform_device *pdev, int idx) engine->sram_pool = gen_pool_dma_alloc(engine->pool, cesa->sram_size, &engine->sram_dma); - if (engine->sram_pool) - return 0; + if (!engine->sram_pool) { + engine->pool = NULL; + return -ENOMEM; + } - engine->pool = NULL; - return -ENOMEM; + return devm_add_action_or_reset(cesa->dev, mv_cesa_release_sram, + engine); } engine->sram = devm_platform_get_and_ioremap_resource(pdev, idx, &res); @@ -395,13 +399,13 @@ static int mv_cesa_get_sram(struct platform_device *pdev, int idx) if (dma_mapping_error(cesa->dev, engine->sram_dma)) return -ENOMEM; - return 0; + return devm_add_action_or_reset(cesa->dev, mv_cesa_release_sram, engine); } -static void mv_cesa_put_sram(struct platform_device *pdev, int idx) +static void mv_cesa_release_sram(void *data) { - struct mv_cesa_dev *cesa = platform_get_drvdata(pdev); - struct mv_cesa_engine *engine = &cesa->engines[idx]; + struct mv_cesa_engine *engine = data; + struct mv_cesa_dev *cesa = engine->cesa; if (engine->pool) gen_pool_free(engine->pool, (unsigned long)engine->sram_pool, @@ -465,17 +469,16 @@ static int mv_cesa_probe(struct platform_device *pdev) char res_name[16]; engine->id = i; + engine->cesa = cesa; spin_lock_init(&engine->lock); ret = mv_cesa_get_sram(pdev, i); if (ret) - goto err_cleanup; + return ret; irq = platform_get_irq(pdev, i); - if (irq < 0) { - ret = irq; - goto err_cleanup; - } + if (irq < 0) + return irq; engine->irq = irq; @@ -487,18 +490,14 @@ static int mv_cesa_probe(struct platform_device *pdev) engine->clk = devm_clk_get_optional_enabled(dev, res_name); if (IS_ERR(engine->clk)) { engine->clk = devm_clk_get_optional_enabled(dev, NULL); - if (IS_ERR(engine->clk)) { - ret = PTR_ERR(engine->clk); - goto err_cleanup; - } + if (IS_ERR(engine->clk)) + return PTR_ERR(engine->clk); } snprintf(res_name, sizeof(res_name), "cesaz%u", i); engine->zclk = devm_clk_get_optional_enabled(dev, res_name); - if (IS_ERR(engine->zclk)) { - ret = PTR_ERR(engine->zclk); - goto err_cleanup; - } + if (IS_ERR(engine->zclk)) + return PTR_ERR(engine->zclk); engine->regs = cesa->regs + CESA_ENGINE_OFF(i); @@ -516,7 +515,7 @@ static int mv_cesa_probe(struct platform_device *pdev) dev_name(&pdev->dev), engine); if (ret) - goto err_cleanup; + return ret; /* Set affinity */ cpu = cpumask_local_spread(engine->id, NUMA_NO_NODE); @@ -532,29 +531,19 @@ static int mv_cesa_probe(struct platform_device *pdev) ret = mv_cesa_add_algs(cesa); if (ret) { cesa_dev = NULL; - goto err_cleanup; + return ret; } dev_info(dev, "CESA device successfully registered\n"); return 0; - -err_cleanup: - for (i = 0; i < caps->nengines; i++) - mv_cesa_put_sram(pdev, i); - - return ret; } static void mv_cesa_remove(struct platform_device *pdev) { struct mv_cesa_dev *cesa = platform_get_drvdata(pdev); - int i; mv_cesa_remove_algs(cesa); - - for (i = 0; i < cesa->caps->nengines; i++) - mv_cesa_put_sram(pdev, i); } static const struct platform_device_id mv_cesa_plat_id_table[] = { diff --git a/drivers/crypto/marvell/cesa/cesa.h b/drivers/crypto/marvell/cesa/cesa.h index 18f9f28040a6..44351b252861 100644 --- a/drivers/crypto/marvell/cesa/cesa.h +++ b/drivers/crypto/marvell/cesa/cesa.h @@ -415,6 +415,7 @@ struct mv_cesa_dev_dma { * @zclk: engine zclk * @max_req_len: maximum chunk length (useful to create the TDMA chain) * @int_mask: interrupt mask cache + * @cesa: back-pointer to the parent CESA device * @pool: memory pool pointing to the memory region reserved in * SRAM * @queue: fifo of the pending crypto requests @@ -441,6 +442,7 @@ struct mv_cesa_engine { struct clk *zclk; size_t max_req_len; u32 int_mask; + struct mv_cesa_dev *cesa; struct gen_pool *pool; struct crypto_queue queue; atomic_t load;