diff options
author | Alex Porosanu <alexandru.porosanu@freescale.com> | 2013-09-09 11:56:32 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2013-09-13 07:43:55 -0400 |
commit | b1f996e0b3b00c98f0ac8ffef1a6572cbc735bbc (patch) | |
tree | 8f6ecb80263398bef489cc6f7a555230fbcc0531 /drivers/crypto | |
parent | 04cddbfe6b5f334aa337a1a9797eb8914822f2f8 (diff) |
crypto: caam - uninstantiate RNG state handle 0 if instantiated by caam driver
If the caam driver module instantiates the RNG state handle 0, then
upon the removal of the module, the RNG state handle is left
initialized. This patch takes care of reverting the state of the
handle back to its previous uninstantatied state.
Signed-off-by: Alex Porosanu <alexandru.porosanu@freescale.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto')
-rw-r--r-- | drivers/crypto/caam/ctrl.c | 57 | ||||
-rw-r--r-- | drivers/crypto/caam/intern.h | 6 |
2 files changed, 57 insertions, 6 deletions
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index 3ad032f570ae..9e9215ac130e 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c | |||
@@ -44,6 +44,17 @@ static void build_instantiation_desc(u32 *desc) | |||
44 | append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT); | 44 | append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT); |
45 | } | 45 | } |
46 | 46 | ||
47 | /* Descriptor for deinstantiation of State Handle 0 of the RNG block. */ | ||
48 | static void build_deinstantiation_desc(u32 *desc) | ||
49 | { | ||
50 | init_job_desc(desc, 0); | ||
51 | |||
52 | /* Uninstantiate State Handle 0 */ | ||
53 | append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG | | ||
54 | OP_ALG_AS_INITFINAL); | ||
55 | |||
56 | append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT); | ||
57 | } | ||
47 | 58 | ||
48 | /* | 59 | /* |
49 | * run_descriptor_deco0 - runs a descriptor on DECO0, under direct control of | 60 | * run_descriptor_deco0 - runs a descriptor on DECO0, under direct control of |
@@ -59,7 +70,7 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc) | |||
59 | struct caam_full __iomem *topregs; | 70 | struct caam_full __iomem *topregs; |
60 | unsigned int timeout = 100000; | 71 | unsigned int timeout = 100000; |
61 | u32 deco_dbg_reg, flags; | 72 | u32 deco_dbg_reg, flags; |
62 | int i, ret = 0; | 73 | int i; |
63 | 74 | ||
64 | /* Set the bit to request direct access to DECO0 */ | 75 | /* Set the bit to request direct access to DECO0 */ |
65 | topregs = (struct caam_full __iomem *)ctrlpriv->ctrl; | 76 | topregs = (struct caam_full __iomem *)ctrlpriv->ctrl; |
@@ -102,11 +113,6 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc) | |||
102 | cpu_relax(); | 113 | cpu_relax(); |
103 | } while ((deco_dbg_reg & DESC_DBG_DECO_STAT_VALID) && --timeout); | 114 | } while ((deco_dbg_reg & DESC_DBG_DECO_STAT_VALID) && --timeout); |
104 | 115 | ||
105 | if (!timeout) { | ||
106 | dev_err(ctrldev, "failed to instantiate RNG\n"); | ||
107 | ret = -EIO; | ||
108 | } | ||
109 | |||
110 | /* Mark the DECO as free */ | 116 | /* Mark the DECO as free */ |
111 | clrbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE); | 117 | clrbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE); |
112 | 118 | ||
@@ -146,6 +152,39 @@ static int instantiate_rng(struct device *ctrldev) | |||
146 | return ret; | 152 | return ret; |
147 | } | 153 | } |
148 | 154 | ||
155 | /* | ||
156 | * deinstantiate_rng - builds and executes a descriptor on DECO0, | ||
157 | * which deinitializes the RNG block. | ||
158 | * @ctrldev - pointer to device | ||
159 | * | ||
160 | * Return: - 0 if no error occurred | ||
161 | * - -ENOMEM if there isn't enough memory to allocate the descriptor | ||
162 | * - -ENODEV if DECO0 couldn't be acquired | ||
163 | * - -EAGAIN if an error occurred when executing the descriptor | ||
164 | */ | ||
165 | static int deinstantiate_rng(struct device *ctrldev) | ||
166 | { | ||
167 | u32 *desc; | ||
168 | int i, ret = 0; | ||
169 | |||
170 | desc = kmalloc(CAAM_CMD_SZ * 3, GFP_KERNEL); | ||
171 | if (!desc) | ||
172 | return -ENOMEM; | ||
173 | |||
174 | /* Create the descriptor for deinstantating RNG State Handle 0 */ | ||
175 | build_deinstantiation_desc(desc); | ||
176 | |||
177 | /* Try to run it through DECO0 */ | ||
178 | ret = run_descriptor_deco0(ctrldev, desc); | ||
179 | |||
180 | if (ret) | ||
181 | dev_err(ctrldev, "failed to deinstantiate RNG\n"); | ||
182 | |||
183 | kfree(desc); | ||
184 | |||
185 | return ret; | ||
186 | } | ||
187 | |||
149 | static int caam_remove(struct platform_device *pdev) | 188 | static int caam_remove(struct platform_device *pdev) |
150 | { | 189 | { |
151 | struct device *ctrldev; | 190 | struct device *ctrldev; |
@@ -165,6 +204,10 @@ static int caam_remove(struct platform_device *pdev) | |||
165 | irq_dispose_mapping(jrpriv->irq); | 204 | irq_dispose_mapping(jrpriv->irq); |
166 | } | 205 | } |
167 | 206 | ||
207 | /* De-initialize RNG if it was initialized by this driver. */ | ||
208 | if (ctrlpriv->rng4_init) | ||
209 | deinstantiate_rng(ctrldev); | ||
210 | |||
168 | /* Shut down debug views */ | 211 | /* Shut down debug views */ |
169 | #ifdef CONFIG_DEBUG_FS | 212 | #ifdef CONFIG_DEBUG_FS |
170 | debugfs_remove_recursive(ctrlpriv->dfs_root); | 213 | debugfs_remove_recursive(ctrlpriv->dfs_root); |
@@ -384,6 +427,8 @@ static int caam_probe(struct platform_device *pdev) | |||
384 | return ret; | 427 | return ret; |
385 | } | 428 | } |
386 | 429 | ||
430 | ctrlpriv->rng4_init = 1; | ||
431 | |||
387 | /* Enable RDB bit so that RNG works faster */ | 432 | /* Enable RDB bit so that RNG works faster */ |
388 | setbits32(&topregs->ctrl.scfgr, SCFGR_RDBENABLE); | 433 | setbits32(&topregs->ctrl.scfgr, SCFGR_RDBENABLE); |
389 | } | 434 | } |
diff --git a/drivers/crypto/caam/intern.h b/drivers/crypto/caam/intern.h index 34c4b9f7fbfa..ada24294c729 100644 --- a/drivers/crypto/caam/intern.h +++ b/drivers/crypto/caam/intern.h | |||
@@ -87,6 +87,12 @@ struct caam_drv_private { | |||
87 | /* list of registered hash algorithms (mk generic context handle?) */ | 87 | /* list of registered hash algorithms (mk generic context handle?) */ |
88 | struct list_head hash_list; | 88 | struct list_head hash_list; |
89 | 89 | ||
90 | /* RNG4 block */ | ||
91 | bool rng4_init; /* If RNG4 block is initialized by this driver, | ||
92 | then this will be set; if it was initialized | ||
93 | by another entity (e.g. u-boot), it will be | ||
94 | cleared. */ | ||
95 | |||
90 | /* | 96 | /* |
91 | * debugfs entries for developer view into driver/device | 97 | * debugfs entries for developer view into driver/device |
92 | * variables at runtime. | 98 | * variables at runtime. |