Commit 51b44fc8 authored by Boris BREZILLON's avatar Boris BREZILLON Committed by Herbert Xu

crypto: mv_cesa - use gen_pool to reserve the SRAM memory region

The mv_cesa driver currently expects the SRAM memory region to be passed
as a platform device resource.

This approach implies two drawbacks:
- the DT representation is wrong
- the only one that can access the SRAM is the crypto engine

The last point is particularly annoying in some cases: for example on
armada 370, a small region of the crypto SRAM is used to implement the
cpuidle, which means you would not be able to enable both cpuidle and the
CESA driver.

To address that problem, we explicitly define the SRAM device in the DT
and then reference the sram node from the crypto engine node.

Also note that the old way of retrieving the SRAM memory region is still
supported, or in other words, backward compatibility is preserved.
Signed-off-by: default avatarBoris Brezillon <boris.brezillon@free-electrons.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 1c075486
...@@ -2,21 +2,29 @@ Marvell Cryptographic Engines And Security Accelerator ...@@ -2,21 +2,29 @@ Marvell Cryptographic Engines And Security Accelerator
Required properties: Required properties:
- compatible : should be "marvell,orion-crypto" - compatible : should be "marvell,orion-crypto"
- reg : base physical address of the engine and length of memory mapped - reg: base physical address of the engine and length of memory mapped
region, followed by base physical address of sram and its memory region. Can also contain an entry for the SRAM attached to the CESA,
length but this representation is deprecated and marvell,crypto-srams should
- reg-names : "regs" , "sram"; be used instead
- interrupts : interrupt number - reg-names: "regs". Can contain an "sram" entry, but this representation
is deprecated and marvell,crypto-srams should be used instead
- interrupts: interrupt number
- clocks: reference to the crypto engines clocks. This property is only - clocks: reference to the crypto engines clocks. This property is only
required for Dove platforms required for Dove platforms
- marvell,crypto-srams: phandle to crypto SRAM definitions
Optional properties:
- marvell,crypto-sram-size: SRAM size reserved for crypto operations, if not
specified the whole SRAM is used (2KB)
Examples: Examples:
crypto@30000 { crypto@30000 {
compatible = "marvell,orion-crypto"; compatible = "marvell,orion-crypto";
reg = <0x30000 0x10000>, reg = <0x30000 0x10000>;
<0x4000000 0x800>; reg-names = "regs";
reg-names = "regs" , "sram";
interrupts = <22>; interrupts = <22>;
marvell,crypto-srams = <&crypto_sram>;
marvell,crypto-sram-size = <0x600>;
status = "okay"; status = "okay";
}; };
...@@ -165,6 +165,7 @@ config CRYPTO_DEV_MV_CESA ...@@ -165,6 +165,7 @@ config CRYPTO_DEV_MV_CESA
select CRYPTO_AES select CRYPTO_AES
select CRYPTO_BLKCIPHER select CRYPTO_BLKCIPHER
select CRYPTO_HASH select CRYPTO_HASH
select SRAM
help help
This driver allows you to utilize the Cryptographic Engines and This driver allows you to utilize the Cryptographic Engines and
Security Accelerator (CESA) which can be found on the Marvell Orion Security Accelerator (CESA) which can be found on the Marvell Orion
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <crypto/aes.h> #include <crypto/aes.h>
#include <crypto/algapi.h> #include <crypto/algapi.h>
#include <linux/crypto.h> #include <linux/crypto.h>
#include <linux/genalloc.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/kthread.h> #include <linux/kthread.h>
...@@ -29,6 +30,8 @@ ...@@ -29,6 +30,8 @@
#define MAX_HW_HASH_SIZE 0xFFFF #define MAX_HW_HASH_SIZE 0xFFFF
#define MV_CESA_EXPIRE 500 /* msec */ #define MV_CESA_EXPIRE 500 /* msec */
#define MV_CESA_DEFAULT_SRAM_SIZE 2048
/* /*
* STM: * STM:
* /---------------------------------------\ * /---------------------------------------\
...@@ -83,6 +86,8 @@ struct req_progress { ...@@ -83,6 +86,8 @@ struct req_progress {
struct crypto_priv { struct crypto_priv {
void __iomem *reg; void __iomem *reg;
void __iomem *sram; void __iomem *sram;
struct gen_pool *sram_pool;
dma_addr_t sram_dma;
int irq; int irq;
struct clk *clk; struct clk *clk;
struct task_struct *queue_th; struct task_struct *queue_th;
...@@ -1019,6 +1024,39 @@ static struct ahash_alg mv_hmac_sha1_alg = { ...@@ -1019,6 +1024,39 @@ static struct ahash_alg mv_hmac_sha1_alg = {
} }
}; };
static int mv_cesa_get_sram(struct platform_device *pdev,
struct crypto_priv *cp)
{
struct resource *res;
u32 sram_size = MV_CESA_DEFAULT_SRAM_SIZE;
of_property_read_u32(pdev->dev.of_node, "marvell,crypto-sram-size",
&sram_size);
cp->sram_size = sram_size;
cp->sram_pool = of_get_named_gen_pool(&pdev->dev.of_node,
"marvell,crypto-srams", 0);
if (cp->sram_pool) {
cp->sram = gen_pool_dma_alloc(cp->sram_pool, sram_size,
&cp->sram_dma);
if (cp->sram)
return 0;
return -ENOMEM;
}
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"sram");
if (!res || resource_size(res) < cp->sram_size)
return -EINVAL;
cp->sram = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(cp->sram))
return PTR_ERR(cp->sram);
return 0;
}
static int mv_probe(struct platform_device *pdev) static int mv_probe(struct platform_device *pdev)
{ {
struct crypto_priv *cp; struct crypto_priv *cp;
...@@ -1047,18 +1085,11 @@ static int mv_probe(struct platform_device *pdev) ...@@ -1047,18 +1085,11 @@ static int mv_probe(struct platform_device *pdev)
goto err; goto err;
} }
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram"); ret = mv_cesa_get_sram(pdev, cp);
if (!res) { if (ret)
ret = -ENXIO;
goto err; goto err;
}
cp->sram_size = resource_size(res);
cp->max_req_size = cp->sram_size - SRAM_CFG_SPACE; cp->max_req_size = cp->sram_size - SRAM_CFG_SPACE;
cp->sram = ioremap(res->start, cp->sram_size);
if (!cp->sram) {
ret = -ENOMEM;
goto err;
}
if (pdev->dev.of_node) if (pdev->dev.of_node)
irq = irq_of_parse_and_map(pdev->dev.of_node, 0); irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
...@@ -1066,7 +1097,7 @@ static int mv_probe(struct platform_device *pdev) ...@@ -1066,7 +1097,7 @@ static int mv_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0 || irq == NO_IRQ) { if (irq < 0 || irq == NO_IRQ) {
ret = irq; ret = irq;
goto err_unmap_sram; goto err;
} }
cp->irq = irq; cp->irq = irq;
...@@ -1076,7 +1107,7 @@ static int mv_probe(struct platform_device *pdev) ...@@ -1076,7 +1107,7 @@ static int mv_probe(struct platform_device *pdev)
cp->queue_th = kthread_run(queue_manag, cp, "mv_crypto"); cp->queue_th = kthread_run(queue_manag, cp, "mv_crypto");
if (IS_ERR(cp->queue_th)) { if (IS_ERR(cp->queue_th)) {
ret = PTR_ERR(cp->queue_th); ret = PTR_ERR(cp->queue_th);
goto err_unmap_sram; goto err;
} }
ret = request_irq(irq, crypto_int, 0, dev_name(&pdev->dev), ret = request_irq(irq, crypto_int, 0, dev_name(&pdev->dev),
...@@ -1134,8 +1165,6 @@ static int mv_probe(struct platform_device *pdev) ...@@ -1134,8 +1165,6 @@ static int mv_probe(struct platform_device *pdev)
} }
err_thread: err_thread:
kthread_stop(cp->queue_th); kthread_stop(cp->queue_th);
err_unmap_sram:
iounmap(cp->sram);
err: err:
kfree(cp); kfree(cp);
cpg = NULL; cpg = NULL;
...@@ -1155,7 +1184,6 @@ static int mv_remove(struct platform_device *pdev) ...@@ -1155,7 +1184,6 @@ static int mv_remove(struct platform_device *pdev)
kthread_stop(cp->queue_th); kthread_stop(cp->queue_th);
free_irq(cp->irq, cp); free_irq(cp->irq, cp);
memset(cp->sram, 0, cp->sram_size); memset(cp->sram, 0, cp->sram_size);
iounmap(cp->sram);
if (!IS_ERR(cp->clk)) { if (!IS_ERR(cp->clk)) {
clk_disable_unprepare(cp->clk); clk_disable_unprepare(cp->clk);
......
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