return crypto_set_driver_name(alg);
 }
 
+static void crypto_free_instance(struct crypto_instance *inst)
+{
+       if (!inst->alg.cra_type->free) {
+               inst->tmpl->free(inst);
+               return;
+       }
+
+       inst->alg.cra_type->free(inst);
+}
+
 static void crypto_destroy_instance(struct crypto_alg *alg)
 {
        struct crypto_instance *inst = (void *)alg;
        struct crypto_template *tmpl = inst->tmpl;
 
-       tmpl->free(inst);
+       crypto_free_instance(inst);
        crypto_tmpl_put(tmpl);
 }
 
 
        hlist_for_each_entry_safe(inst, n, list, list) {
                BUG_ON(atomic_read(&inst->alg.cra_refcnt) != 1);
-               tmpl->free(inst);
+               crypto_free_instance(inst);
        }
        crypto_remove_final(&users);
 }
 
 #include <linux/skbuff.h>
 
 struct crypto_aead;
+struct crypto_instance;
 struct module;
 struct rtattr;
 struct seq_file;
        void (*show)(struct seq_file *m, struct crypto_alg *alg);
        int (*report)(struct sk_buff *skb, struct crypto_alg *alg);
        struct crypto_alg *(*lookup)(const char *name, u32 type, u32 mask);
+       void (*free)(struct crypto_instance *inst);
 
        unsigned int type;
        unsigned int maskclear;