Skip to content

Commit f086fd1

Browse files
martin-kaiserherbertx
authored andcommitted
hwrng: imx-rngc - simplify interrupt mask/unmask
Use a simpler approach for masking / unmasking the rngc interrupt: The interrupt is unmasked while self-test is running and when the rngc driver is used by the hwrng core. Mask the interrupt again when self test is finished, regardless of self test success or failure. Unmask the interrupt in the init function. Add a cleanup function where the rngc interrupt is masked again. Signed-off-by: Martin Kaiser <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
1 parent b9957fc commit f086fd1

File tree

1 file changed

+28
-15
lines changed

1 file changed

+28
-15
lines changed

drivers/char/hw_random/imx-rngc.c

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -111,17 +111,11 @@ static int imx_rngc_self_test(struct imx_rngc *rngc)
111111
writel(cmd | RNGC_CMD_SELF_TEST, rngc->base + RNGC_COMMAND);
112112

113113
ret = wait_for_completion_timeout(&rngc->rng_op_done, RNGC_TIMEOUT);
114-
if (!ret) {
115-
imx_rngc_irq_mask_clear(rngc);
114+
imx_rngc_irq_mask_clear(rngc);
115+
if (!ret)
116116
return -ETIMEDOUT;
117-
}
118-
119-
if (rngc->err_reg != 0) {
120-
imx_rngc_irq_mask_clear(rngc);
121-
return -EIO;
122-
}
123117

124-
return 0;
118+
return rngc->err_reg ? -EIO : 0;
125119
}
126120

127121
static int imx_rngc_read(struct hwrng *rng, void *data, size_t max, bool wait)
@@ -185,10 +179,10 @@ static int imx_rngc_init(struct hwrng *rng)
185179
cmd = readl(rngc->base + RNGC_COMMAND);
186180
writel(cmd | RNGC_CMD_CLR_ERR, rngc->base + RNGC_COMMAND);
187181

182+
imx_rngc_irq_unmask(rngc);
183+
188184
/* create seed, repeat while there is some statistical error */
189185
do {
190-
imx_rngc_irq_unmask(rngc);
191-
192186
/* seed creation */
193187
cmd = readl(rngc->base + RNGC_COMMAND);
194188
writel(cmd | RNGC_CMD_SEED, rngc->base + RNGC_COMMAND);
@@ -197,14 +191,16 @@ static int imx_rngc_init(struct hwrng *rng)
197191
RNGC_TIMEOUT);
198192

199193
if (!ret) {
200-
imx_rngc_irq_mask_clear(rngc);
201-
return -ETIMEDOUT;
194+
ret = -ETIMEDOUT;
195+
goto err;
202196
}
203197

204198
} while (rngc->err_reg == RNGC_ERROR_STATUS_STAT_ERR);
205199

206-
if (rngc->err_reg)
207-
return -EIO;
200+
if (rngc->err_reg) {
201+
ret = -EIO;
202+
goto err;
203+
}
208204

209205
/*
210206
* enable automatic seeding, the rngc creates a new seed automatically
@@ -214,7 +210,23 @@ static int imx_rngc_init(struct hwrng *rng)
214210
ctrl |= RNGC_CTRL_AUTO_SEED;
215211
writel(ctrl, rngc->base + RNGC_CONTROL);
216212

213+
/*
214+
* if initialisation was successful, we keep the interrupt
215+
* unmasked until imx_rngc_cleanup is called
216+
* we mask the interrupt ourselves if we return an error
217+
*/
217218
return 0;
219+
220+
err:
221+
imx_rngc_irq_mask_clear(rngc);
222+
return ret;
223+
}
224+
225+
static void imx_rngc_cleanup(struct hwrng *rng)
226+
{
227+
struct imx_rngc *rngc = container_of(rng, struct imx_rngc, rng);
228+
229+
imx_rngc_irq_mask_clear(rngc);
218230
}
219231

220232
static int imx_rngc_probe(struct platform_device *pdev)
@@ -272,6 +284,7 @@ static int imx_rngc_probe(struct platform_device *pdev)
272284
rngc->rng.name = pdev->name;
273285
rngc->rng.init = imx_rngc_init;
274286
rngc->rng.read = imx_rngc_read;
287+
rngc->rng.cleanup = imx_rngc_cleanup;
275288

276289
rngc->dev = &pdev->dev;
277290
platform_set_drvdata(pdev, rngc);

0 commit comments

Comments
 (0)