struct timespec64 req_time;
 };
 
-static DEFINE_MUTEX(hpre_alg_lock);
-static unsigned int hpre_active_devs;
-
 static int hpre_alloc_req_id(struct hpre_ctx *ctx)
 {
        unsigned long flags;
 
 int hpre_algs_register(void)
 {
-       int ret = 0;
-
-       mutex_lock(&hpre_alg_lock);
-       if (++hpre_active_devs == 1) {
-               rsa.base.cra_flags = 0;
-               ret = crypto_register_akcipher(&rsa);
-               if (ret)
-                       goto unlock;
+       int ret;
+
+       rsa.base.cra_flags = 0;
+       ret = crypto_register_akcipher(&rsa);
+       if (ret)
+               return ret;
 #ifdef CONFIG_CRYPTO_DH
-               ret = crypto_register_kpp(&dh);
-               if (ret) {
-                       crypto_unregister_akcipher(&rsa);
-                       goto unlock;
-               }
+       ret = crypto_register_kpp(&dh);
+       if (ret)
+               crypto_unregister_akcipher(&rsa);
 #endif
-       }
 
-unlock:
-       mutex_unlock(&hpre_alg_lock);
        return ret;
 }
 
 void hpre_algs_unregister(void)
 {
-       mutex_lock(&hpre_alg_lock);
-       if (--hpre_active_devs == 0) {
-               crypto_unregister_akcipher(&rsa);
+       crypto_unregister_akcipher(&rsa);
 #ifdef CONFIG_CRYPTO_DH
-               crypto_unregister_kpp(&dh);
+       crypto_unregister_kpp(&dh);
 #endif
-       }
-       mutex_unlock(&hpre_alg_lock);
 }
 
 #define HPRE_SQE_MASK_OFFSET           8
 #define HPRE_SQE_MASK_LEN              24
 
-static struct hisi_qm_list hpre_devices;
 static const char hpre_name[] = "hisi_hpre";
 static struct dentry *hpre_debugfs_root;
 static const struct pci_device_id hpre_dev_ids[] = {
        const char *msg;
 };
 
+static struct hisi_qm_list hpre_devices = {
+       .register_to_crypto     = hpre_algs_register,
+       .unregister_from_crypto = hpre_algs_unregister,
+};
+
 static const char * const hpre_debug_file_name[] = {
        [HPRE_CURRENT_QM]   = "current_qm",
        [HPRE_CLEAR_ENABLE] = "rdclr_en",
        if (ret)
                dev_warn(&pdev->dev, "init debugfs fail!\n");
 
-       hisi_qm_add_to_list(qm, &hpre_devices);
-
-       ret = hpre_algs_register();
+       ret = hisi_qm_alg_register(qm, &hpre_devices);
        if (ret < 0) {
                pci_err(pdev, "fail to register algs to crypto!\n");
                goto err_with_qm_start;
        if (qm->fun_type == QM_HW_PF && vfs_num) {
                ret = hisi_qm_sriov_enable(pdev, vfs_num);
                if (ret < 0)
-                       goto err_with_crypto_register;
+                       goto err_with_alg_register;
        }
 
        return 0;
 
-err_with_crypto_register:
-       hpre_algs_unregister();
+err_with_alg_register:
+       hisi_qm_alg_unregister(qm, &hpre_devices);
 
 err_with_qm_start:
-       hisi_qm_del_from_list(qm, &hpre_devices);
        hpre_debugfs_exit(qm);
        hisi_qm_stop(qm, QM_NORMAL);
 
        int ret;
 
        hisi_qm_wait_task_finish(qm, &hpre_devices);
-       hpre_algs_unregister();
-       hisi_qm_del_from_list(qm, &hpre_devices);
+       hisi_qm_alg_unregister(qm, &hpre_devices);
        if (qm->fun_type == QM_HW_PF && qm->vfs_num) {
                ret = hisi_qm_sriov_disable(pdev, qm->is_frozen);
                if (ret) {
 
 
 }
 
+/**
+ * hisi_qm_alg_register() - Register alg to crypto and add qm to qm_list.
+ * @qm: The qm needs add.
+ * @qm_list: The qm list.
+ *
+ * This function adds qm to qm list, and will register algorithm to
+ * crypto when the qm list is empty.
+ */
+int hisi_qm_alg_register(struct hisi_qm *qm, struct hisi_qm_list *qm_list)
+{
+       int flag = 0;
+       int ret = 0;
+
+       mutex_lock(&qm_list->lock);
+       if (list_empty(&qm_list->list))
+               flag = 1;
+       list_add_tail(&qm->list, &qm_list->list);
+       mutex_unlock(&qm_list->lock);
+
+       if (flag) {
+               ret = qm_list->register_to_crypto();
+               if (ret) {
+                       mutex_lock(&qm_list->lock);
+                       list_del(&qm->list);
+                       mutex_unlock(&qm_list->lock);
+               }
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(hisi_qm_alg_register);
+
+/**
+ * hisi_qm_alg_unregister() - Unregister alg from crypto and delete qm from
+ * qm list.
+ * @qm: The qm needs delete.
+ * @qm_list: The qm list.
+ *
+ * This function deletes qm from qm list, and will unregister algorithm
+ * from crypto when the qm list is empty.
+ */
+void hisi_qm_alg_unregister(struct hisi_qm *qm, struct hisi_qm_list *qm_list)
+{
+       mutex_lock(&qm_list->lock);
+       list_del(&qm->list);
+       mutex_unlock(&qm_list->lock);
+
+       if (list_empty(&qm_list->list))
+               qm_list->unregister_from_crypto();
+}
+EXPORT_SYMBOL_GPL(hisi_qm_alg_unregister);
+
 /**
  * hisi_qm_init() - Initialize configures about qm.
  * @qm: The qm needing init.
 
 struct hisi_qm_list {
        struct mutex lock;
        struct list_head list;
+       int (*register_to_crypto)(void);
+       void (*unregister_from_crypto)(void);
 };
 
 struct hisi_qm {
        mutex_init(&qm_list->lock);
 }
 
-static inline void hisi_qm_add_to_list(struct hisi_qm *qm,
-                                      struct hisi_qm_list *qm_list)
-{
-       mutex_lock(&qm_list->lock);
-       list_add_tail(&qm->list, &qm_list->list);
-       mutex_unlock(&qm_list->lock);
-}
-
-static inline void hisi_qm_del_from_list(struct hisi_qm *qm,
-                                        struct hisi_qm_list *qm_list)
-{
-       mutex_lock(&qm_list->lock);
-       list_del(&qm->list);
-       mutex_unlock(&qm_list->lock);
-}
-
 int hisi_qm_init(struct hisi_qm *qm);
 void hisi_qm_uninit(struct hisi_qm *qm);
 int hisi_qm_start(struct hisi_qm *qm);
 void hisi_qm_free_qps(struct hisi_qp **qps, int qp_num);
 void hisi_qm_dev_shutdown(struct pci_dev *pdev);
 void hisi_qm_wait_task_finish(struct hisi_qm *qm, struct hisi_qm_list *qm_list);
+int hisi_qm_alg_register(struct hisi_qm *qm, struct hisi_qm_list *qm_list);
+void hisi_qm_alg_unregister(struct hisi_qm *qm, struct hisi_qm_list *qm_list);
 #endif
 
 #define SEC_SQE_AEAD_FLAG      3
 #define SEC_SQE_DONE           0x1
 
-static atomic_t sec_active_devs;
-
 /* Get an en/de-cipher queue cyclically to balance load over queues of TFM */
 static inline int sec_alloc_queue_id(struct sec_ctx *ctx, struct sec_req *req)
 {
 
 int sec_register_to_crypto(void)
 {
-       int ret = 0;
+       int ret;
 
        /* To avoid repeat register */
-       if (atomic_add_return(1, &sec_active_devs) == 1) {
-               ret = crypto_register_skciphers(sec_skciphers,
-                                               ARRAY_SIZE(sec_skciphers));
-               if (ret)
-                       return ret;
-
-               ret = crypto_register_aeads(sec_aeads, ARRAY_SIZE(sec_aeads));
-               if (ret)
-                       goto reg_aead_fail;
-       }
-
-       return ret;
-
-reg_aead_fail:
-       crypto_unregister_skciphers(sec_skciphers, ARRAY_SIZE(sec_skciphers));
+       ret = crypto_register_skciphers(sec_skciphers,
+                                       ARRAY_SIZE(sec_skciphers));
+       if (ret)
+               return ret;
 
+       ret = crypto_register_aeads(sec_aeads, ARRAY_SIZE(sec_aeads));
+       if (ret)
+               crypto_unregister_skciphers(sec_skciphers,
+                                           ARRAY_SIZE(sec_skciphers));
        return ret;
 }
 
 void sec_unregister_from_crypto(void)
 {
-       if (atomic_sub_return(1, &sec_active_devs) == 0) {
-               crypto_unregister_skciphers(sec_skciphers,
-                                           ARRAY_SIZE(sec_skciphers));
-               crypto_unregister_aeads(sec_aeads, ARRAY_SIZE(sec_aeads));
-       }
+       crypto_unregister_skciphers(sec_skciphers,
+                                   ARRAY_SIZE(sec_skciphers));
+       crypto_unregister_aeads(sec_aeads, ARRAY_SIZE(sec_aeads));
 }
 
 
 static const char sec_name[] = "hisi_sec2";
 static struct dentry *sec_debugfs_root;
-static struct hisi_qm_list sec_devices;
+
+static struct hisi_qm_list sec_devices = {
+       .register_to_crypto     = sec_register_to_crypto,
+       .unregister_from_crypto = sec_unregister_from_crypto,
+};
 
 static const struct sec_hw_error sec_hw_errors[] = {
        {.int_msk = BIT(0), .msg = "sec_axi_rresp_err_rint"},
        if (ret)
                pci_warn(pdev, "Failed to init debugfs!\n");
 
-       hisi_qm_add_to_list(qm, &sec_devices);
-
-       ret = sec_register_to_crypto();
+       ret = hisi_qm_alg_register(qm, &sec_devices);
        if (ret < 0) {
                pr_err("Failed to register driver to crypto.\n");
-               goto err_remove_from_list;
+               goto err_qm_stop;
        }
 
        if (qm->fun_type == QM_HW_PF && vfs_num) {
                ret = hisi_qm_sriov_enable(pdev, vfs_num);
                if (ret < 0)
-                       goto err_crypto_unregister;
+                       goto err_alg_unregister;
        }
 
        return 0;
 
-err_crypto_unregister:
-       sec_unregister_from_crypto();
+err_alg_unregister:
+       hisi_qm_alg_unregister(qm, &sec_devices);
 
-err_remove_from_list:
-       hisi_qm_del_from_list(qm, &sec_devices);
+err_qm_stop:
        sec_debugfs_exit(qm);
        hisi_qm_stop(qm, QM_NORMAL);
 
        struct hisi_qm *qm = &sec->qm;
 
        hisi_qm_wait_task_finish(qm, &sec_devices);
-       sec_unregister_from_crypto();
-
-       hisi_qm_del_from_list(qm, &sec_devices);
-
+       hisi_qm_alg_unregister(qm, &sec_devices);
        if (qm->fun_type == QM_HW_PF && qm->vfs_num)
                hisi_qm_sriov_disable(pdev, qm->is_frozen);
 
 
 
 int hisi_zip_register_to_crypto(void)
 {
-       int ret = 0;
+       int ret;
 
        ret = crypto_register_acomp(&hisi_zip_acomp_zlib);
        if (ret) {
 
 
 static const char hisi_zip_name[] = "hisi_zip";
 static struct dentry *hzip_debugfs_root;
-static struct hisi_qm_list zip_devices;
 
 struct hisi_zip_hw_error {
        u32 int_msk;
        u32 offset;
 };
 
+static struct hisi_qm_list zip_devices = {
+       .register_to_crypto     = hisi_zip_register_to_crypto,
+       .unregister_from_crypto = hisi_zip_unregister_from_crypto,
+};
+
 static struct zip_dfx_item zip_dfx_files[] = {
        {"send_cnt", offsetof(struct hisi_zip_dfx, send_cnt)},
        {"recv_cnt", offsetof(struct hisi_zip_dfx, recv_cnt)},
 
        ret = hisi_qm_start(qm);
        if (ret)
-               goto err_qm_uninit;
+               goto err_dev_err_uninit;
 
        ret = hisi_zip_debugfs_init(hisi_zip);
        if (ret)
                dev_err(&pdev->dev, "Failed to init debugfs (%d)!\n", ret);
 
-       hisi_qm_add_to_list(qm, &zip_devices);
+       ret = hisi_qm_alg_register(qm, &zip_devices);
+       if (ret < 0) {
+               pci_err(pdev, "Failed to register driver to crypto.\n");
+               goto err_qm_stop;
+       }
 
        if (qm->uacce) {
                ret = uacce_register(qm->uacce);
                if (ret)
-                       goto err_qm_uninit;
+                       goto err_qm_alg_unregister;
        }
 
        if (qm->fun_type == QM_HW_PF && vfs_num > 0) {
                ret = hisi_qm_sriov_enable(pdev, vfs_num);
                if (ret < 0)
-                       goto err_remove_from_list;
+                       goto err_qm_alg_unregister;
        }
 
        return 0;
 
-err_remove_from_list:
-       hisi_qm_del_from_list(qm, &zip_devices);
+err_qm_alg_unregister:
+       hisi_qm_alg_unregister(qm, &zip_devices);
+
+err_qm_stop:
        hisi_zip_debugfs_exit(hisi_zip);
        hisi_qm_stop(qm, QM_NORMAL);
+
+err_dev_err_uninit:
+       hisi_qm_dev_err_uninit(qm);
+
 err_qm_uninit:
        hisi_qm_uninit(qm);
 
        struct hisi_qm *qm = &hisi_zip->qm;
 
        hisi_qm_wait_task_finish(qm, &zip_devices);
+       hisi_qm_alg_unregister(qm, &zip_devices);
+
        if (qm->fun_type == QM_HW_PF && qm->vfs_num)
                hisi_qm_sriov_disable(pdev, qm->is_frozen);
 
        hisi_zip_debugfs_exit(hisi_zip);
        hisi_qm_stop(qm, QM_NORMAL);
-
        hisi_qm_dev_err_uninit(qm);
        hisi_qm_uninit(qm);
-       hisi_qm_del_from_list(qm, &zip_devices);
 }
 
 static const struct pci_error_handlers hisi_zip_err_handler = {
                goto err_pci;
        }
 
-       ret = hisi_zip_register_to_crypto();
-       if (ret < 0) {
-               pr_err("Failed to register driver to crypto.\n");
-               goto err_crypto;
-       }
-
        return 0;
 
-err_crypto:
-       pci_unregister_driver(&hisi_zip_pci_driver);
 err_pci:
        hisi_zip_unregister_debugfs();
 
 
 static void __exit hisi_zip_exit(void)
 {
-       hisi_zip_unregister_from_crypto();
        pci_unregister_driver(&hisi_zip_pci_driver);
        hisi_zip_unregister_debugfs();
 }