Commit 8256e683 authored by Gary R Hook's avatar Gary R Hook Committed by Herbert Xu

crypto: ccp - Refactor code supporting the CCP's RNG

Make the RNG support code common (where possible) in
preparation for adding a v5 device.
Signed-off-by: default avatarGary R Hook <gary.hook@amd.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 58a690b7
...@@ -307,35 +307,6 @@ static int ccp_perform_ecc(struct ccp_op *op) ...@@ -307,35 +307,6 @@ static int ccp_perform_ecc(struct ccp_op *op)
return ccp_do_cmd(op, cr, ARRAY_SIZE(cr)); return ccp_do_cmd(op, cr, ARRAY_SIZE(cr));
} }
static int ccp_trng_read(struct hwrng *rng, void *data, size_t max, bool wait)
{
struct ccp_device *ccp = container_of(rng, struct ccp_device, hwrng);
u32 trng_value;
int len = min_t(int, sizeof(trng_value), max);
/*
* Locking is provided by the caller so we can update device
* hwrng-related fields safely
*/
trng_value = ioread32(ccp->io_regs + TRNG_OUT_REG);
if (!trng_value) {
/* Zero is returned if not data is available or if a
* bad-entropy error is present. Assume an error if
* we exceed TRNG_RETRIES reads of zero.
*/
if (ccp->hwrng_retries++ > TRNG_RETRIES)
return -EIO;
return 0;
}
/* Reset the counter and save the rng value */
ccp->hwrng_retries = 0;
memcpy(data, &trng_value, len);
return len;
}
static int ccp_init(struct ccp_device *ccp) static int ccp_init(struct ccp_device *ccp)
{ {
struct device *dev = ccp->dev; struct device *dev = ccp->dev;
...@@ -495,17 +466,6 @@ static void ccp_destroy(struct ccp_device *ccp) ...@@ -495,17 +466,6 @@ static void ccp_destroy(struct ccp_device *ccp)
/* Remove this device from the list of available units first */ /* Remove this device from the list of available units first */
ccp_del_device(ccp); ccp_del_device(ccp);
/* Unregister the DMA engine */
ccp_dmaengine_unregister(ccp);
/* Unregister the RNG */
hwrng_unregister(&ccp->hwrng);
/* Stop the queue kthreads */
for (i = 0; i < ccp->cmd_q_count; i++)
if (ccp->cmd_q[i].kthread)
kthread_stop(ccp->cmd_q[i].kthread);
/* Build queue interrupt mask (two interrupt masks per queue) */ /* Build queue interrupt mask (two interrupt masks per queue) */
qim = 0; qim = 0;
for (i = 0; i < ccp->cmd_q_count; i++) { for (i = 0; i < ccp->cmd_q_count; i++) {
...@@ -523,6 +483,17 @@ static void ccp_destroy(struct ccp_device *ccp) ...@@ -523,6 +483,17 @@ static void ccp_destroy(struct ccp_device *ccp)
} }
iowrite32(qim, ccp->io_regs + IRQ_STATUS_REG); iowrite32(qim, ccp->io_regs + IRQ_STATUS_REG);
/* Unregister the DMA engine */
ccp_dmaengine_unregister(ccp);
/* Unregister the RNG */
hwrng_unregister(&ccp->hwrng);
/* Stop the queue kthreads */
for (i = 0; i < ccp->cmd_q_count; i++)
if (ccp->cmd_q[i].kthread)
kthread_stop(ccp->cmd_q[i].kthread);
ccp->free_irq(ccp); ccp->free_irq(ccp);
for (i = 0; i < ccp->cmd_q_count; i++) for (i = 0; i < ccp->cmd_q_count; i++)
......
...@@ -409,6 +409,34 @@ struct ccp_device *ccp_alloc_struct(struct device *dev) ...@@ -409,6 +409,34 @@ struct ccp_device *ccp_alloc_struct(struct device *dev)
return ccp; return ccp;
} }
int ccp_trng_read(struct hwrng *rng, void *data, size_t max, bool wait)
{
struct ccp_device *ccp = container_of(rng, struct ccp_device, hwrng);
u32 trng_value;
int len = min_t(int, sizeof(trng_value), max);
/* Locking is provided by the caller so we can update device
* hwrng-related fields safely
*/
trng_value = ioread32(ccp->io_regs + TRNG_OUT_REG);
if (!trng_value) {
/* Zero is returned if not data is available or if a
* bad-entropy error is present. Assume an error if
* we exceed TRNG_RETRIES reads of zero.
*/
if (ccp->hwrng_retries++ > TRNG_RETRIES)
return -EIO;
return 0;
}
/* Reset the counter and save the rng value */
ccp->hwrng_retries = 0;
memcpy(data, &trng_value, len);
return len;
}
#ifdef CONFIG_PM #ifdef CONFIG_PM
bool ccp_queues_suspended(struct ccp_device *ccp) bool ccp_queues_suspended(struct ccp_device *ccp)
{ {
......
...@@ -440,6 +440,7 @@ void ccp_del_device(struct ccp_device *ccp); ...@@ -440,6 +440,7 @@ void ccp_del_device(struct ccp_device *ccp);
struct ccp_device *ccp_alloc_struct(struct device *dev); struct ccp_device *ccp_alloc_struct(struct device *dev);
bool ccp_queues_suspended(struct ccp_device *ccp); bool ccp_queues_suspended(struct ccp_device *ccp);
int ccp_cmd_queue_thread(void *data); int ccp_cmd_queue_thread(void *data);
int ccp_trng_read(struct hwrng *rng, void *data, size_t max, bool wait);
int ccp_run_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd); int ccp_run_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment