Path: blob/master/drivers/crypto/hisilicon/zip/zip_crypto.c
51347 views
// SPDX-License-Identifier: GPL-2.01/* Copyright (c) 2019 HiSilicon Limited. */2#include <crypto/internal/acompress.h>3#include <linux/bitfield.h>4#include <linux/bitmap.h>5#include <linux/dma-mapping.h>6#include <linux/scatterlist.h>7#include "zip.h"89/* hisi_zip_sqe dw3 */10#define HZIP_BD_STATUS_M GENMASK(7, 0)11/* hisi_zip_sqe dw7 */12#define HZIP_IN_SGE_DATA_OFFSET_M GENMASK(23, 0)13#define HZIP_SQE_TYPE_M GENMASK(31, 28)14/* hisi_zip_sqe dw8 */15#define HZIP_OUT_SGE_DATA_OFFSET_M GENMASK(23, 0)16/* hisi_zip_sqe dw9 */17#define HZIP_REQ_TYPE_M GENMASK(7, 0)18#define HZIP_ALG_TYPE_DEFLATE 0x0119#define HZIP_ALG_TYPE_LZ4 0x0420#define HZIP_BUF_TYPE_M GENMASK(11, 8)21#define HZIP_SGL 0x122#define HZIP_WIN_SIZE_M GENMASK(15, 12)23#define HZIP_16K_WINSZ 0x22425#define HZIP_ALG_PRIORITY 30026#define HZIP_SGL_SGE_NR 102728#define HZIP_ALG_DEFLATE GENMASK(5, 4)29#define HZIP_ALG_LZ4 BIT(8)3031static DEFINE_MUTEX(zip_algs_lock);32static unsigned int zip_available_devs;3334enum hisi_zip_alg_type {35HZIP_ALG_TYPE_COMP = 0,36HZIP_ALG_TYPE_DECOMP = 1,37};3839enum {40HZIP_QPC_COMP,41HZIP_QPC_DECOMP,42HZIP_CTX_Q_NUM43};4445#define GET_REQ_FROM_SQE(sqe) ((u64)(sqe)->dw26 | (u64)(sqe)->dw27 << 32)46#define COMP_NAME_TO_TYPE(alg_name) \47(!strcmp((alg_name), "deflate") ? HZIP_ALG_TYPE_DEFLATE : \48(!strcmp((alg_name), "lz4") ? HZIP_ALG_TYPE_LZ4 : 0))4950struct hisi_zip_req {51struct acomp_req *req;52struct hisi_acc_hw_sgl *hw_src;53struct hisi_acc_hw_sgl *hw_dst;54dma_addr_t dma_src;55dma_addr_t dma_dst;56struct hisi_zip_qp_ctx *qp_ctx;57u16 req_id;58};5960struct hisi_zip_req_q {61struct hisi_zip_req *q;62unsigned long *req_bitmap;63spinlock_t req_lock;64u16 size;65};6667struct hisi_zip_qp_ctx {68struct hisi_qp *qp;69struct hisi_zip_req_q req_q;70struct hisi_acc_sgl_pool *sgl_pool;71struct hisi_zip *zip_dev;72struct hisi_zip_ctx *ctx;73u8 req_type;74};7576struct hisi_zip_sqe_ops {77u8 sqe_type;78void (*fill_addr)(struct hisi_zip_sqe *sqe, struct hisi_zip_req *req);79void (*fill_buf_size)(struct hisi_zip_sqe *sqe, struct hisi_zip_req *req);80void (*fill_buf_type)(struct hisi_zip_sqe *sqe, u8 buf_type);81void (*fill_req_type)(struct hisi_zip_sqe *sqe, u8 req_type);82void (*fill_win_size)(struct hisi_zip_sqe *sqe, u8 win_size);83void (*fill_tag)(struct hisi_zip_sqe *sqe, struct hisi_zip_req *req);84void (*fill_sqe_type)(struct hisi_zip_sqe *sqe, u8 sqe_type);85u32 (*get_status)(struct hisi_zip_sqe *sqe);86u32 (*get_dstlen)(struct hisi_zip_sqe *sqe);87};8889struct hisi_zip_ctx {90struct hisi_zip_qp_ctx qp_ctx[HZIP_CTX_Q_NUM];91const struct hisi_zip_sqe_ops *ops;92bool fallback;93};9495static int sgl_sge_nr_set(const char *val, const struct kernel_param *kp)96{97int ret;98u16 n;99100if (!val)101return -EINVAL;102103ret = kstrtou16(val, 10, &n);104if (ret || n == 0 || n > HISI_ACC_SGL_SGE_NR_MAX)105return -EINVAL;106107return param_set_ushort(val, kp);108}109110static const struct kernel_param_ops sgl_sge_nr_ops = {111.set = sgl_sge_nr_set,112.get = param_get_ushort,113};114115static u16 sgl_sge_nr = HZIP_SGL_SGE_NR;116module_param_cb(sgl_sge_nr, &sgl_sge_nr_ops, &sgl_sge_nr, 0444);117MODULE_PARM_DESC(sgl_sge_nr, "Number of sge in sgl(1-255)");118119static int hisi_zip_fallback_do_work(struct acomp_req *acomp_req, bool is_decompress)120{121ACOMP_FBREQ_ON_STACK(fbreq, acomp_req);122int ret;123124if (!is_decompress)125ret = crypto_acomp_compress(fbreq);126else127ret = crypto_acomp_decompress(fbreq);128if (ret) {129pr_err("failed to do fallback work, ret=%d\n", ret);130return ret;131}132133acomp_req->dlen = fbreq->dlen;134return ret;135}136137static struct hisi_zip_req *hisi_zip_create_req(struct hisi_zip_qp_ctx *qp_ctx,138struct acomp_req *req)139{140struct hisi_zip_req_q *req_q = &qp_ctx->req_q;141struct hisi_zip_req *q = req_q->q;142struct hisi_zip_req *req_cache;143int req_id;144145spin_lock(&req_q->req_lock);146147req_id = find_first_zero_bit(req_q->req_bitmap, req_q->size);148if (req_id >= req_q->size) {149spin_unlock(&req_q->req_lock);150dev_dbg(&qp_ctx->qp->qm->pdev->dev, "req cache is full!\n");151return ERR_PTR(-EAGAIN);152}153set_bit(req_id, req_q->req_bitmap);154155spin_unlock(&req_q->req_lock);156157req_cache = q + req_id;158req_cache->req_id = req_id;159req_cache->req = req;160req_cache->qp_ctx = qp_ctx;161162return req_cache;163}164165static void hisi_zip_remove_req(struct hisi_zip_qp_ctx *qp_ctx,166struct hisi_zip_req *req)167{168struct hisi_zip_req_q *req_q = &qp_ctx->req_q;169170spin_lock(&req_q->req_lock);171clear_bit(req->req_id, req_q->req_bitmap);172spin_unlock(&req_q->req_lock);173}174175static void hisi_zip_fill_addr(struct hisi_zip_sqe *sqe, struct hisi_zip_req *req)176{177sqe->source_addr_l = lower_32_bits(req->dma_src);178sqe->source_addr_h = upper_32_bits(req->dma_src);179sqe->dest_addr_l = lower_32_bits(req->dma_dst);180sqe->dest_addr_h = upper_32_bits(req->dma_dst);181}182183static void hisi_zip_fill_buf_size(struct hisi_zip_sqe *sqe, struct hisi_zip_req *req)184{185struct acomp_req *a_req = req->req;186187sqe->input_data_length = a_req->slen;188sqe->dest_avail_out = a_req->dlen;189}190191static void hisi_zip_fill_buf_type(struct hisi_zip_sqe *sqe, u8 buf_type)192{193u32 val;194195val = sqe->dw9 & ~HZIP_BUF_TYPE_M;196val |= FIELD_PREP(HZIP_BUF_TYPE_M, buf_type);197sqe->dw9 = val;198}199200static void hisi_zip_fill_req_type(struct hisi_zip_sqe *sqe, u8 req_type)201{202u32 val;203204val = sqe->dw9 & ~HZIP_REQ_TYPE_M;205val |= FIELD_PREP(HZIP_REQ_TYPE_M, req_type);206sqe->dw9 = val;207}208209static void hisi_zip_fill_win_size(struct hisi_zip_sqe *sqe, u8 win_size)210{211u32 val;212213val = sqe->dw9 & ~HZIP_WIN_SIZE_M;214val |= FIELD_PREP(HZIP_WIN_SIZE_M, win_size);215sqe->dw9 = val;216}217218static void hisi_zip_fill_tag(struct hisi_zip_sqe *sqe, struct hisi_zip_req *req)219{220sqe->dw26 = lower_32_bits((u64)req);221sqe->dw27 = upper_32_bits((u64)req);222}223224static void hisi_zip_fill_sqe_type(struct hisi_zip_sqe *sqe, u8 sqe_type)225{226u32 val;227228val = sqe->dw7 & ~HZIP_SQE_TYPE_M;229val |= FIELD_PREP(HZIP_SQE_TYPE_M, sqe_type);230sqe->dw7 = val;231}232233static void hisi_zip_fill_sqe(struct hisi_zip_ctx *ctx, struct hisi_zip_sqe *sqe,234u8 req_type, struct hisi_zip_req *req)235{236const struct hisi_zip_sqe_ops *ops = ctx->ops;237238memset(sqe, 0, sizeof(struct hisi_zip_sqe));239240ops->fill_addr(sqe, req);241ops->fill_buf_size(sqe, req);242ops->fill_buf_type(sqe, HZIP_SGL);243ops->fill_req_type(sqe, req_type);244ops->fill_win_size(sqe, HZIP_16K_WINSZ);245ops->fill_tag(sqe, req);246ops->fill_sqe_type(sqe, ops->sqe_type);247}248249static int hisi_zip_do_work(struct hisi_zip_qp_ctx *qp_ctx,250struct hisi_zip_req *req)251{252struct hisi_acc_sgl_pool *pool = qp_ctx->sgl_pool;253struct hisi_zip_dfx *dfx = &qp_ctx->zip_dev->dfx;254struct acomp_req *a_req = req->req;255struct hisi_qp *qp = qp_ctx->qp;256struct device *dev = &qp->qm->pdev->dev;257struct hisi_zip_sqe zip_sqe;258int ret;259260if (unlikely(!a_req->src || !a_req->slen || !a_req->dst || !a_req->dlen))261return -EINVAL;262263req->hw_src = hisi_acc_sg_buf_map_to_hw_sgl(dev, a_req->src, pool,264req->req_id << 1, &req->dma_src,265DMA_TO_DEVICE);266if (IS_ERR(req->hw_src)) {267dev_err(dev, "failed to map the src buffer to hw sgl (%ld)!\n",268PTR_ERR(req->hw_src));269return PTR_ERR(req->hw_src);270}271272req->hw_dst = hisi_acc_sg_buf_map_to_hw_sgl(dev, a_req->dst, pool,273(req->req_id << 1) + 1,274&req->dma_dst, DMA_FROM_DEVICE);275if (IS_ERR(req->hw_dst)) {276ret = PTR_ERR(req->hw_dst);277dev_err(dev, "failed to map the dst buffer to hw sgl (%d)!\n",278ret);279goto err_unmap_input;280}281282hisi_zip_fill_sqe(qp_ctx->ctx, &zip_sqe, qp_ctx->req_type, req);283284/* send command to start a task */285atomic64_inc(&dfx->send_cnt);286ret = hisi_qp_send(qp, &zip_sqe);287if (unlikely(ret < 0)) {288atomic64_inc(&dfx->send_busy_cnt);289ret = -EAGAIN;290dev_dbg_ratelimited(dev, "failed to send request!\n");291goto err_unmap_output;292}293294return -EINPROGRESS;295296err_unmap_output:297hisi_acc_sg_buf_unmap(dev, a_req->dst, req->hw_dst, DMA_FROM_DEVICE);298err_unmap_input:299hisi_acc_sg_buf_unmap(dev, a_req->src, req->hw_src, DMA_TO_DEVICE);300return ret;301}302303static u32 hisi_zip_get_status(struct hisi_zip_sqe *sqe)304{305return sqe->dw3 & HZIP_BD_STATUS_M;306}307308static u32 hisi_zip_get_dstlen(struct hisi_zip_sqe *sqe)309{310return sqe->produced;311}312313static void hisi_zip_acomp_cb(struct hisi_qp *qp, void *data)314{315struct hisi_zip_sqe *sqe = data;316struct hisi_zip_req *req = (struct hisi_zip_req *)GET_REQ_FROM_SQE(sqe);317struct hisi_zip_qp_ctx *qp_ctx = req->qp_ctx;318const struct hisi_zip_sqe_ops *ops = qp_ctx->ctx->ops;319struct hisi_zip_dfx *dfx = &qp_ctx->zip_dev->dfx;320struct device *dev = &qp->qm->pdev->dev;321struct acomp_req *acomp_req = req->req;322int err = 0;323u32 status;324325atomic64_inc(&dfx->recv_cnt);326status = ops->get_status(sqe);327if (unlikely(status != 0 && status != HZIP_NC_ERR)) {328dev_err(dev, "%scompress fail in qp%u: %u, output: %u\n",329(qp->alg_type == 0) ? "" : "de", qp->qp_id, status,330sqe->produced);331atomic64_inc(&dfx->err_bd_cnt);332err = -EIO;333}334335hisi_acc_sg_buf_unmap(dev, acomp_req->dst, req->hw_dst, DMA_FROM_DEVICE);336hisi_acc_sg_buf_unmap(dev, acomp_req->src, req->hw_src, DMA_TO_DEVICE);337338acomp_req->dlen = ops->get_dstlen(sqe);339340if (acomp_req->base.complete)341acomp_request_complete(acomp_req, err);342343hisi_zip_remove_req(qp_ctx, req);344}345346static int hisi_zip_acompress(struct acomp_req *acomp_req)347{348struct hisi_zip_ctx *ctx = crypto_tfm_ctx(acomp_req->base.tfm);349struct hisi_zip_qp_ctx *qp_ctx = &ctx->qp_ctx[HZIP_QPC_COMP];350struct hisi_zip_req *req;351struct device *dev;352int ret;353354if (ctx->fallback)355return hisi_zip_fallback_do_work(acomp_req, 0);356357dev = &qp_ctx->qp->qm->pdev->dev;358359req = hisi_zip_create_req(qp_ctx, acomp_req);360if (IS_ERR(req))361return PTR_ERR(req);362363ret = hisi_zip_do_work(qp_ctx, req);364if (unlikely(ret != -EINPROGRESS)) {365dev_info_ratelimited(dev, "failed to do compress (%d)!\n", ret);366hisi_zip_remove_req(qp_ctx, req);367}368369return ret;370}371372static int hisi_zip_adecompress(struct acomp_req *acomp_req)373{374struct hisi_zip_ctx *ctx = crypto_tfm_ctx(acomp_req->base.tfm);375struct hisi_zip_qp_ctx *qp_ctx = &ctx->qp_ctx[HZIP_QPC_DECOMP];376struct hisi_zip_req *req;377struct device *dev;378int ret;379380if (ctx->fallback)381return hisi_zip_fallback_do_work(acomp_req, 1);382383dev = &qp_ctx->qp->qm->pdev->dev;384385req = hisi_zip_create_req(qp_ctx, acomp_req);386if (IS_ERR(req))387return PTR_ERR(req);388389ret = hisi_zip_do_work(qp_ctx, req);390if (unlikely(ret != -EINPROGRESS)) {391dev_info_ratelimited(dev, "failed to do decompress (%d)!\n",392ret);393hisi_zip_remove_req(qp_ctx, req);394}395396return ret;397}398399static int hisi_zip_decompress(struct acomp_req *acomp_req)400{401return hisi_zip_fallback_do_work(acomp_req, 1);402}403404static const struct hisi_zip_sqe_ops hisi_zip_ops = {405.sqe_type = 0x3,406.fill_addr = hisi_zip_fill_addr,407.fill_buf_size = hisi_zip_fill_buf_size,408.fill_buf_type = hisi_zip_fill_buf_type,409.fill_req_type = hisi_zip_fill_req_type,410.fill_win_size = hisi_zip_fill_win_size,411.fill_tag = hisi_zip_fill_tag,412.fill_sqe_type = hisi_zip_fill_sqe_type,413.get_status = hisi_zip_get_status,414.get_dstlen = hisi_zip_get_dstlen,415};416417static int hisi_zip_ctx_init(struct hisi_zip_ctx *hisi_zip_ctx, u8 req_type, int node)418{419struct hisi_qp *qps[HZIP_CTX_Q_NUM] = { NULL };420struct hisi_zip_qp_ctx *qp_ctx;421u8 alg_type[HZIP_CTX_Q_NUM];422struct hisi_zip *hisi_zip;423int ret, i;424425/* alg_type = 0 for compress, 1 for decompress in hw sqe */426for (i = 0; i < HZIP_CTX_Q_NUM; i++)427alg_type[i] = i;428429ret = zip_create_qps(qps, HZIP_CTX_Q_NUM, node, alg_type);430if (ret) {431pr_err("failed to create zip qps (%d)!\n", ret);432return -ENODEV;433}434435hisi_zip = container_of(qps[0]->qm, struct hisi_zip, qm);436437for (i = 0; i < HZIP_CTX_Q_NUM; i++) {438qp_ctx = &hisi_zip_ctx->qp_ctx[i];439qp_ctx->ctx = hisi_zip_ctx;440qp_ctx->zip_dev = hisi_zip;441qp_ctx->req_type = req_type;442qp_ctx->qp = qps[i];443}444445hisi_zip_ctx->ops = &hisi_zip_ops;446447return 0;448}449450static void hisi_zip_ctx_exit(struct hisi_zip_ctx *hisi_zip_ctx)451{452struct hisi_qp *qps[HZIP_CTX_Q_NUM] = { NULL };453int i;454455for (i = 0; i < HZIP_CTX_Q_NUM; i++)456qps[i] = hisi_zip_ctx->qp_ctx[i].qp;457458hisi_qm_free_qps(qps, HZIP_CTX_Q_NUM);459}460461static int hisi_zip_create_req_q(struct hisi_zip_ctx *ctx)462{463u16 q_depth = ctx->qp_ctx[0].qp->sq_depth;464struct hisi_zip_req_q *req_q;465int i, ret;466467for (i = 0; i < HZIP_CTX_Q_NUM; i++) {468req_q = &ctx->qp_ctx[i].req_q;469req_q->size = q_depth;470471req_q->req_bitmap = bitmap_zalloc(req_q->size, GFP_KERNEL);472if (!req_q->req_bitmap) {473ret = -ENOMEM;474if (i == 0)475return ret;476477goto err_free_comp_q;478}479spin_lock_init(&req_q->req_lock);480481req_q->q = kcalloc(req_q->size, sizeof(struct hisi_zip_req),482GFP_KERNEL);483if (!req_q->q) {484ret = -ENOMEM;485if (i == 0)486goto err_free_comp_bitmap;487else488goto err_free_decomp_bitmap;489}490}491492return 0;493494err_free_decomp_bitmap:495bitmap_free(ctx->qp_ctx[HZIP_QPC_DECOMP].req_q.req_bitmap);496err_free_comp_q:497kfree(ctx->qp_ctx[HZIP_QPC_COMP].req_q.q);498err_free_comp_bitmap:499bitmap_free(ctx->qp_ctx[HZIP_QPC_COMP].req_q.req_bitmap);500return ret;501}502503static void hisi_zip_release_req_q(struct hisi_zip_ctx *ctx)504{505int i;506507for (i = 0; i < HZIP_CTX_Q_NUM; i++) {508kfree(ctx->qp_ctx[i].req_q.q);509bitmap_free(ctx->qp_ctx[i].req_q.req_bitmap);510}511}512513static int hisi_zip_create_sgl_pool(struct hisi_zip_ctx *ctx)514{515u16 q_depth = ctx->qp_ctx[0].qp->sq_depth;516struct hisi_zip_qp_ctx *tmp;517struct device *dev;518int i;519520for (i = 0; i < HZIP_CTX_Q_NUM; i++) {521tmp = &ctx->qp_ctx[i];522dev = &tmp->qp->qm->pdev->dev;523tmp->sgl_pool = hisi_acc_create_sgl_pool(dev, q_depth << 1,524sgl_sge_nr);525if (IS_ERR(tmp->sgl_pool)) {526if (i == 1)527goto err_free_sgl_pool0;528return -ENOMEM;529}530}531532return 0;533534err_free_sgl_pool0:535hisi_acc_free_sgl_pool(&ctx->qp_ctx[HZIP_QPC_COMP].qp->qm->pdev->dev,536ctx->qp_ctx[HZIP_QPC_COMP].sgl_pool);537return -ENOMEM;538}539540static void hisi_zip_release_sgl_pool(struct hisi_zip_ctx *ctx)541{542int i;543544for (i = 0; i < HZIP_CTX_Q_NUM; i++)545hisi_acc_free_sgl_pool(&ctx->qp_ctx[i].qp->qm->pdev->dev,546ctx->qp_ctx[i].sgl_pool);547}548549static void hisi_zip_set_acomp_cb(struct hisi_zip_ctx *ctx,550void (*fn)(struct hisi_qp *, void *))551{552int i;553554for (i = 0; i < HZIP_CTX_Q_NUM; i++)555ctx->qp_ctx[i].qp->req_cb = fn;556}557558static int hisi_zip_acomp_init(struct crypto_acomp *tfm)559{560const char *alg_name = crypto_tfm_alg_name(&tfm->base);561struct hisi_zip_ctx *ctx = crypto_tfm_ctx(&tfm->base);562struct device *dev;563int ret;564565ret = hisi_zip_ctx_init(ctx, COMP_NAME_TO_TYPE(alg_name), tfm->base.node);566if (ret) {567pr_err("failed to init ctx (%d)!\n", ret);568goto switch_to_soft;569}570571dev = &ctx->qp_ctx[0].qp->qm->pdev->dev;572573ret = hisi_zip_create_req_q(ctx);574if (ret) {575dev_err(dev, "failed to create request queue (%d)!\n", ret);576goto err_ctx_exit;577}578579ret = hisi_zip_create_sgl_pool(ctx);580if (ret) {581dev_err(dev, "failed to create sgl pool (%d)!\n", ret);582goto err_release_req_q;583}584585hisi_zip_set_acomp_cb(ctx, hisi_zip_acomp_cb);586587return 0;588589err_release_req_q:590hisi_zip_release_req_q(ctx);591err_ctx_exit:592hisi_zip_ctx_exit(ctx);593switch_to_soft:594ctx->fallback = true;595return 0;596}597598static void hisi_zip_acomp_exit(struct crypto_acomp *tfm)599{600struct hisi_zip_ctx *ctx = crypto_tfm_ctx(&tfm->base);601602if (ctx->fallback)603return;604605hisi_zip_release_sgl_pool(ctx);606hisi_zip_release_req_q(ctx);607hisi_zip_ctx_exit(ctx);608}609610static struct acomp_alg hisi_zip_acomp_deflate = {611.init = hisi_zip_acomp_init,612.exit = hisi_zip_acomp_exit,613.compress = hisi_zip_acompress,614.decompress = hisi_zip_adecompress,615.base = {616.cra_name = "deflate",617.cra_driver_name = "hisi-deflate-acomp",618.cra_flags = CRYPTO_ALG_ASYNC |619CRYPTO_ALG_NEED_FALLBACK,620.cra_module = THIS_MODULE,621.cra_priority = HZIP_ALG_PRIORITY,622.cra_ctxsize = sizeof(struct hisi_zip_ctx),623}624};625626static int hisi_zip_register_deflate(struct hisi_qm *qm)627{628int ret;629630if (!hisi_zip_alg_support(qm, HZIP_ALG_DEFLATE))631return 0;632633ret = crypto_register_acomp(&hisi_zip_acomp_deflate);634if (ret)635dev_err(&qm->pdev->dev, "failed to register to deflate (%d)!\n", ret);636637return ret;638}639640static void hisi_zip_unregister_deflate(struct hisi_qm *qm)641{642if (!hisi_zip_alg_support(qm, HZIP_ALG_DEFLATE))643return;644645crypto_unregister_acomp(&hisi_zip_acomp_deflate);646}647648static struct acomp_alg hisi_zip_acomp_lz4 = {649.init = hisi_zip_acomp_init,650.exit = hisi_zip_acomp_exit,651.compress = hisi_zip_acompress,652.decompress = hisi_zip_decompress,653.base = {654.cra_name = "lz4",655.cra_driver_name = "hisi-lz4-acomp",656.cra_flags = CRYPTO_ALG_ASYNC |657CRYPTO_ALG_NEED_FALLBACK,658.cra_module = THIS_MODULE,659.cra_priority = HZIP_ALG_PRIORITY,660.cra_ctxsize = sizeof(struct hisi_zip_ctx),661}662};663664static int hisi_zip_register_lz4(struct hisi_qm *qm)665{666int ret;667668if (!hisi_zip_alg_support(qm, HZIP_ALG_LZ4))669return 0;670671ret = crypto_register_acomp(&hisi_zip_acomp_lz4);672if (ret)673dev_err(&qm->pdev->dev, "failed to register to LZ4 (%d)!\n", ret);674675return ret;676}677678static void hisi_zip_unregister_lz4(struct hisi_qm *qm)679{680if (!hisi_zip_alg_support(qm, HZIP_ALG_LZ4))681return;682683crypto_unregister_acomp(&hisi_zip_acomp_lz4);684}685686int hisi_zip_register_to_crypto(struct hisi_qm *qm)687{688int ret = 0;689690mutex_lock(&zip_algs_lock);691if (zip_available_devs) {692zip_available_devs++;693goto unlock;694}695696ret = hisi_zip_register_deflate(qm);697if (ret)698goto unlock;699700ret = hisi_zip_register_lz4(qm);701if (ret)702goto unreg_deflate;703704zip_available_devs++;705mutex_unlock(&zip_algs_lock);706707return 0;708709unreg_deflate:710hisi_zip_unregister_deflate(qm);711unlock:712mutex_unlock(&zip_algs_lock);713return ret;714}715716void hisi_zip_unregister_from_crypto(struct hisi_qm *qm)717{718mutex_lock(&zip_algs_lock);719if (--zip_available_devs)720goto unlock;721722hisi_zip_unregister_deflate(qm);723hisi_zip_unregister_lz4(qm);724725unlock:726mutex_unlock(&zip_algs_lock);727}728729730