2012-12-21 17:04:50

by Mark Greer

[permalink] [raw]
Subject: [PATCH 00/10] crypto: omap-aes - Updates & New Functionality

From: "Mark A. Greer" <[email protected]>

[This supersedes the omap-aes driver patches sent in the
"crypto: omap-aes updates" series sent a few weeks ago.]

This patch series does several things to the omap-aes crypto
driver including:
- converting to use pm_runtime
- adding suspend/resume support
- converting to use dmaengine API
- adding device tree support
- adding OMAP4/AM33XX support
- adding CTR support
- some misc. cleanups

The patches are based on the current k.o. kernel, plus:
- the ARM hwmod, etc patches from
"[PATCH 00/15] OMAP SHAM & AES Crypto Updates"
(http://marc.info/?l=linux-omap&m=135610732120447&w=2)
- the EDMA dmaengine patches submitted by Matt Porter
"[RFC PATCH v3 00/16] DMA Engine support for AM33XX]"
(https://lkml.org/lkml/2012/10/18/256)
- some misc patches required by the EDMA patches
- a hack to fix the compilation error that the current k.o. kernel has

A working examle is here:

[email protected]:mgreeraz/linux-mag.git submitted/crypto/aes

Mark A. Greer (10):
crypto: omap-aes - Remmove unnecessary pr_info noise
crypto: omap-aes - Don't reset controller for every operation
crypto: omap-aes - Convert to use pm_runtime API
crypto: omap-aes - Add suspend/resume support
crypto: omap-aes - Add code to use dmaengine API
crypto: omap-aes - Remove usage of private DMA API
crypto: omap-aes - Add Device Tree Support
crypto: omap-aes - Convert to dma_request_slave_channel_compat()
crypto: omap-aes - Add OMAP4/AM33XX AES Support
crypto: omap-aes - Add CTR algorithm Support

drivers/crypto/omap-aes.c | 654 ++++++++++++++++++++++++++++++++++------------
1 file changed, 480 insertions(+), 174 deletions(-)

--
1.7.12



2012-12-21 17:05:10

by Mark Greer

[permalink] [raw]
Subject: [PATCH 01/10] crypto: omap-aes - Remmove unnecessary pr_info noise

From: "Mark A. Greer" <[email protected]>

Remove the unnecessary pr_info() calls from omap_aes_probe()
and omap_aes_mod_init().

CC: Dmitry Kasatkin <[email protected]>
Signed-off-by: Mark A. Greer <[email protected]>
---
drivers/crypto/omap-aes.c | 4 ----
1 file changed, 4 deletions(-)

diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index e66e8ee..481da71 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -880,8 +880,6 @@ static int omap_aes_probe(struct platform_device *pdev)
goto err_algs;
}

- pr_info("probe() done\n");
-
return 0;
err_algs:
for (j = 0; j < i; j++)
@@ -938,8 +936,6 @@ static struct platform_driver omap_aes_driver = {

static int __init omap_aes_mod_init(void)
{
- pr_info("loading %s driver\n", "omap-aes");
-
return platform_driver_register(&omap_aes_driver);
}

--
1.7.12

2012-12-21 17:05:10

by Mark Greer

[permalink] [raw]
Subject: [PATCH 02/10] crypto: omap-aes - Don't reset controller for every operation

From: "Mark A. Greer" <[email protected]>

The AES controller only needs to be reset once and that will
be done by the hwmod infrastructure, if possible. Therefore,
remove the reset code from the omap-aes driver.

CC: Dmitry Kasatkin <[email protected]>
Signed-off-by: Mark A. Greer <[email protected]>
---
drivers/crypto/omap-aes.c | 27 ---------------------------
1 file changed, 27 deletions(-)

diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 481da71..33cd783 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -160,19 +160,6 @@ static void omap_aes_write_n(struct omap_aes_dev *dd, u32 offset,
omap_aes_write(dd, offset, *value);
}

-static int omap_aes_wait(struct omap_aes_dev *dd, u32 offset, u32 bit)
-{
- unsigned long timeout = jiffies + DEFAULT_TIMEOUT;
-
- while (!(omap_aes_read(dd, offset) & bit)) {
- if (time_is_before_jiffies(timeout)) {
- dev_err(dd->dev, "omap-aes timeout\n");
- return -ETIMEDOUT;
- }
- }
- return 0;
-}
-
static int omap_aes_hw_init(struct omap_aes_dev *dd)
{
/*
@@ -183,20 +170,6 @@ static int omap_aes_hw_init(struct omap_aes_dev *dd)
clk_enable(dd->iclk);

if (!(dd->flags & FLAGS_INIT)) {
- /* is it necessary to reset before every operation? */
- omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_SOFTRESET,
- AES_REG_MASK_SOFTRESET);
- /*
- * prevent OCP bus error (SRESP) in case an access to the module
- * is performed while the module is coming out of soft reset
- */
- __asm__ __volatile__("nop");
- __asm__ __volatile__("nop");
-
- if (omap_aes_wait(dd, AES_REG_SYSSTATUS,
- AES_REG_SYSSTATUS_RESETDONE))
- return -ETIMEDOUT;
-
dd->flags |= FLAGS_INIT;
dd->err = 0;
}
--
1.7.12

2012-12-21 17:05:12

by Mark Greer

[permalink] [raw]
Subject: [PATCH 04/10] crypto: omap-aes - Add suspend/resume support

From: "Mark A. Greer" <[email protected]>

Add suspend/resume support to the OMAP AES driver.

CC: Dmitry Kasatkin <[email protected]>
Signed-off-by: Mark A. Greer <[email protected]>
---
drivers/crypto/omap-aes.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)

diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index c229852..3262139 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -891,12 +891,31 @@ static int omap_aes_remove(struct platform_device *pdev)
return 0;
}

+#ifdef CONFIG_PM_SLEEP
+static int omap_aes_suspend(struct device *dev)
+{
+ pm_runtime_put_sync(dev);
+ return 0;
+}
+
+static int omap_aes_resume(struct device *dev)
+{
+ pm_runtime_get_sync(dev);
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops omap_aes_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(omap_aes_suspend, omap_aes_resume)
+};
+
static struct platform_driver omap_aes_driver = {
.probe = omap_aes_probe,
.remove = omap_aes_remove,
.driver = {
.name = "omap-aes",
.owner = THIS_MODULE,
+ .pm = &omap_aes_pm_ops,
},
};

--
1.7.12

2012-12-21 17:05:10

by Mark Greer

[permalink] [raw]
Subject: [PATCH 03/10] crypto: omap-aes - Convert to use pm_runtime API

From: "Mark A. Greer" <[email protected]>

Convert the omap-aes crypto driver to use the
pm_runtime API instead of the clk API.

CC: Kevin Hilman <[email protected]>
CC: Dmitry Kasatkin <[email protected]>
Signed-off-by: Mark A. Greer <[email protected]>
---
drivers/crypto/omap-aes.c | 29 +++++++++++------------------
1 file changed, 11 insertions(+), 18 deletions(-)

diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 33cd783..c229852 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -19,10 +19,10 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/scatterlist.h>
#include <linux/dma-mapping.h>
+#include <linux/pm_runtime.h>
#include <linux/io.h>
#include <linux/crypto.h>
#include <linux/interrupt.h>
@@ -96,7 +96,6 @@ struct omap_aes_dev {
struct list_head list;
unsigned long phys_base;
void __iomem *io_base;
- struct clk *iclk;
struct omap_aes_ctx *ctx;
struct device *dev;
unsigned long flags;
@@ -167,7 +166,7 @@ static int omap_aes_hw_init(struct omap_aes_dev *dd)
* It may be long delays between requests.
* Device might go to off mode to save power.
*/
- clk_enable(dd->iclk);
+ pm_runtime_get_sync(dd->dev);

if (!(dd->flags & FLAGS_INIT)) {
dd->flags |= FLAGS_INIT;
@@ -518,7 +517,7 @@ static void omap_aes_finish_req(struct omap_aes_dev *dd, int err)

pr_debug("err: %d\n", err);

- clk_disable(dd->iclk);
+ pm_runtime_put_sync(dd->dev);
dd->flags &= ~FLAGS_BUSY;

req->base.complete(&req->base, err);
@@ -813,26 +812,21 @@ static int omap_aes_probe(struct platform_device *pdev)
else
dd->dma_in = res->start;

- /* Initializing the clock */
- dd->iclk = clk_get(dev, "ick");
- if (IS_ERR(dd->iclk)) {
- dev_err(dev, "clock intialization failed.\n");
- err = PTR_ERR(dd->iclk);
- goto err_res;
- }
-
dd->io_base = ioremap(dd->phys_base, SZ_4K);
if (!dd->io_base) {
dev_err(dev, "can't ioremap\n");
err = -ENOMEM;
- goto err_io;
+ goto err_res;
}

- clk_enable(dd->iclk);
+ pm_runtime_enable(dev);
+ pm_runtime_get_sync(dev);
+
reg = omap_aes_read(dd, AES_REG_REV);
dev_info(dev, "OMAP AES hw accel rev: %u.%u\n",
(reg & AES_REG_REV_MAJOR) >> 4, reg & AES_REG_REV_MINOR);
- clk_disable(dd->iclk);
+
+ pm_runtime_put_sync(dev);

tasklet_init(&dd->done_task, omap_aes_done_task, (unsigned long)dd);
tasklet_init(&dd->queue_task, omap_aes_queue_task, (unsigned long)dd);
@@ -862,8 +856,7 @@ err_dma:
tasklet_kill(&dd->done_task);
tasklet_kill(&dd->queue_task);
iounmap(dd->io_base);
-err_io:
- clk_put(dd->iclk);
+ pm_runtime_disable(dev);
err_res:
kfree(dd);
dd = NULL;
@@ -891,7 +884,7 @@ static int omap_aes_remove(struct platform_device *pdev)
tasklet_kill(&dd->queue_task);
omap_aes_dma_cleanup(dd);
iounmap(dd->io_base);
- clk_put(dd->iclk);
+ pm_runtime_disable(dd->dev);
kfree(dd);
dd = NULL;

--
1.7.12

2012-12-21 17:05:12

by Mark Greer

[permalink] [raw]
Subject: [PATCH 08/10] crypto: omap-aes - Convert to dma_request_slave_channel_compat()

From: "Mark A. Greer" <[email protected]>

Use the dma_request_slave_channel_compat() call instead of
the dma_request_channel() call to request a DMA channel.
This allows the omap-aes driver use different DMA engines.

CC: Dmitry Kasatkin <[email protected]>
Signed-off-by: Mark A. Greer <[email protected]>
---
drivers/crypto/omap-aes.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 68bf22d..e28788e 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -296,15 +296,19 @@ static int omap_aes_dma_init(struct omap_aes_dev *dd)
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);

- dd->dma_lch_in = dma_request_channel(mask, omap_dma_filter_fn,
- &dd->dma_in);
+ dd->dma_lch_in = dma_request_slave_channel_compat(mask,
+ omap_dma_filter_fn,
+ &dd->dma_in,
+ dd->dev, "rx");
if (!dd->dma_lch_in) {
dev_err(dd->dev, "Unable to request in DMA channel\n");
goto err_dma_in;
}

- dd->dma_lch_out = dma_request_channel(mask, omap_dma_filter_fn,
- &dd->dma_out);
+ dd->dma_lch_out = dma_request_slave_channel_compat(mask,
+ omap_dma_filter_fn,
+ &dd->dma_out,
+ dd->dev, "tx");
if (!dd->dma_lch_out) {
dev_err(dd->dev, "Unable to request out DMA channel\n");
goto err_dma_out;
--
1.7.12

2012-12-21 17:05:14

by Mark Greer

[permalink] [raw]
Subject: [PATCH 07/10] crypto: omap-aes - Add Device Tree Support

From: "Mark A. Greer" <[email protected]>

Add Device Tree suport to the omap-aes crypto
driver. Currently, only support for OMAP2 and
OMAP3 is being added but support for OMAP4 will
be added in a subsequent patch.

CC: Dmitry Kasatkin <[email protected]>
Signed-off-by: Mark A. Greer <[email protected]>
---
drivers/crypto/omap-aes.c | 119 ++++++++++++++++++++++++++++++++++++----------
1 file changed, 93 insertions(+), 26 deletions(-)

diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index faf522f..68bf22d 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -25,6 +25,9 @@
#include <linux/dmaengine.h>
#include <linux/omap-dma.h>
#include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
#include <linux/io.h>
#include <linux/crypto.h>
#include <linux/interrupt.h>
@@ -819,11 +822,93 @@ static struct crypto_alg algs[] = {
}
};

+#ifdef CONFIG_OF
+static const struct of_device_id omap_aes_of_match[] = {
+ {
+ .compatible = "ti,omap2-aes",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, omap_aes_of_match);
+
+static int omap_aes_get_res_of(struct omap_aes_dev *dd,
+ struct device *dev, struct resource *res)
+{
+ struct device_node *node = dev->of_node;
+ const struct of_device_id *match;
+ int err = 0;
+
+ match = of_match_device(of_match_ptr(omap_aes_of_match), dev);
+ if (!match) {
+ dev_err(dev, "no compatible OF match\n");
+ err = -EINVAL;
+ goto err;
+ }
+
+ err = of_address_to_resource(node, 0, res);
+ if (err < 0) {
+ dev_err(dev, "can't translate OF node address\n");
+ err = -EINVAL;
+ goto err;
+ }
+
+ dd->dma_out = -1; /* Dummy value that's unused */
+ dd->dma_in = -1; /* Dummy value that's unused */
+
+err:
+ return err;
+}
+#else
+static int omap_aes_get_res_dev(struct omap_aes_dev *dd,
+ struct device *dev, struct resource *res)
+{
+ return -EINVAL;
+}
+#endif
+
+static int omap_aes_get_res_pdev(struct omap_aes_dev *dd,
+ struct platform_device *pdev, struct resource *res)
+{
+ struct device *dev = &pdev->dev;
+ struct resource *r;
+ int err = 0;
+
+ /* Get the base address */
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r) {
+ dev_err(dev, "no MEM resource info\n");
+ err = -ENODEV;
+ goto err;
+ }
+ memcpy(res, r, sizeof(*res));
+
+ /* Get the DMA out channel */
+ r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+ if (!r) {
+ dev_err(dev, "no DMA out resource info\n");
+ err = -ENODEV;
+ goto err;
+ }
+ dd->dma_out = r->start;
+
+ /* Get the DMA in channel */
+ r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+ if (!r) {
+ dev_err(dev, "no DMA in resource info\n");
+ err = -ENODEV;
+ goto err;
+ }
+ dd->dma_in = r->start;
+
+err:
+ return err;
+}
+
static int omap_aes_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct omap_aes_dev *dd;
- struct resource *res;
+ struct resource res;
int err = -ENOMEM, i, j;
u32 reg;

@@ -838,35 +923,18 @@ static int omap_aes_probe(struct platform_device *pdev)
spin_lock_init(&dd->lock);
crypto_init_queue(&dd->queue, OMAP_AES_QUEUE_LENGTH);

- /* Get the base address */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(dev, "invalid resource type\n");
- err = -ENODEV;
+ err = (dev->of_node) ? omap_aes_get_res_of(dd, dev, &res) :
+ omap_aes_get_res_pdev(dd, pdev, &res);
+ if (err)
goto err_res;
- }
- dd->phys_base = res->start;
-
- /* Get the DMA */
- res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!res)
- dev_info(dev, "no DMA info\n");
- else
- dd->dma_out = res->start;
-
- /* Get the DMA */
- res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
- if (!res)
- dev_info(dev, "no DMA info\n");
- else
- dd->dma_in = res->start;
-
- dd->io_base = ioremap(dd->phys_base, SZ_4K);
+
+ dd->io_base = devm_request_and_ioremap(dev, &res);
if (!dd->io_base) {
dev_err(dev, "can't ioremap\n");
err = -ENOMEM;
goto err_res;
}
+ dd->phys_base = res.start;

pm_runtime_enable(dev);
pm_runtime_get_sync(dev);
@@ -904,7 +972,6 @@ err_algs:
err_dma:
tasklet_kill(&dd->done_task);
tasklet_kill(&dd->queue_task);
- iounmap(dd->io_base);
pm_runtime_disable(dev);
err_res:
kfree(dd);
@@ -932,7 +999,6 @@ static int omap_aes_remove(struct platform_device *pdev)
tasklet_kill(&dd->done_task);
tasklet_kill(&dd->queue_task);
omap_aes_dma_cleanup(dd);
- iounmap(dd->io_base);
pm_runtime_disable(dd->dev);
kfree(dd);
dd = NULL;
@@ -965,6 +1031,7 @@ static struct platform_driver omap_aes_driver = {
.name = "omap-aes",
.owner = THIS_MODULE,
.pm = &omap_aes_pm_ops,
+ .of_match_table = omap_aes_of_match,
},
};

--
1.7.12

2012-12-21 17:05:13

by Mark Greer

[permalink] [raw]
Subject: [PATCH 05/10] crypto: omap-aes - Add code to use dmaengine API

From: "Mark A. Greer" <[email protected]>

Add code to use the new dmaengine API alongside
the existing DMA code that uses the private
OMAP DMA API. The API to use is chosen by
defining or undefining 'OMAP_AES_DMA_PRIVATE'.

CC: Russell King <[email protected]>
CC: Dmitry Kasatkin <[email protected]>
Signed-off-by: Mark A. Greer <[email protected]>
---
drivers/crypto/omap-aes.c | 184 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 183 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 3262139..14ec9e2 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -12,6 +12,8 @@
*
*/

+#define OMAP_AES_DMA_PRIVATE
+
#define pr_fmt(fmt) "%s: " fmt, __func__

#include <linux/err.h>
@@ -22,6 +24,8 @@
#include <linux/platform_device.h>
#include <linux/scatterlist.h>
#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/omap-dma.h>
#include <linux/pm_runtime.h>
#include <linux/io.h>
#include <linux/crypto.h>
@@ -29,7 +33,8 @@
#include <crypto/scatterwalk.h>
#include <crypto/aes.h>

-#include <linux/omap-dma.h>
+#define DST_MAXBURST 4
+#define DMA_MIN (DST_MAXBURST * sizeof(u32))

/* OMAP TRM gives bitfields as start:end, where start is the higher bit
number. For example 7:0 */
@@ -110,19 +115,33 @@ struct omap_aes_dev {
struct ablkcipher_request *req;
size_t total;
struct scatterlist *in_sg;
+#ifndef OMAP_AES_DMA_PRIVATE
+ struct scatterlist in_sgl;
+#endif
size_t in_offset;
struct scatterlist *out_sg;
+#ifndef OMAP_AES_DMA_PRIVATE
+ struct scatterlist out_sgl;
+#endif
size_t out_offset;

size_t buflen;
void *buf_in;
size_t dma_size;
int dma_in;
+#ifdef OMAP_AES_DMA_PRIVATE
int dma_lch_in;
+#else
+ struct dma_chan *dma_lch_in;
+#endif
dma_addr_t dma_addr_in;
void *buf_out;
int dma_out;
+#ifdef OMAP_AES_DMA_PRIVATE
int dma_lch_out;
+#else
+ struct dma_chan *dma_lch_out;
+#endif
dma_addr_t dma_addr_out;
};

@@ -187,10 +206,17 @@ static int omap_aes_write_ctrl(struct omap_aes_dev *dd)
return err;

val = 0;
+#ifdef OMAP_AES_DMA_PRIVATE
if (dd->dma_lch_out >= 0)
val |= AES_REG_MASK_DMA_OUT_EN;
if (dd->dma_lch_in >= 0)
val |= AES_REG_MASK_DMA_IN_EN;
+#else
+ if (dd->dma_lch_out != NULL)
+ val |= AES_REG_MASK_DMA_OUT_EN;
+ if (dd->dma_lch_in != NULL)
+ val |= AES_REG_MASK_DMA_IN_EN;
+#endif

mask = AES_REG_MASK_DMA_IN_EN | AES_REG_MASK_DMA_OUT_EN;

@@ -218,6 +244,7 @@ static int omap_aes_write_ctrl(struct omap_aes_dev *dd)

omap_aes_write_mask(dd, AES_REG_CTRL, val, mask);

+#ifdef OMAP_AES_DMA_PRIVATE
/* IN */
omap_set_dma_dest_params(dd->dma_lch_in, 0, OMAP_DMA_AMODE_CONSTANT,
dd->phys_base + AES_REG_DATA, 0, 4);
@@ -231,6 +258,7 @@ static int omap_aes_write_ctrl(struct omap_aes_dev *dd)

omap_set_dma_src_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4);
omap_set_dma_dest_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4);
+#endif

return 0;
}
@@ -256,6 +284,7 @@ static struct omap_aes_dev *omap_aes_find_dev(struct omap_aes_ctx *ctx)
return dd;
}

+#ifdef OMAP_AES_DMA_PRIVATE
static void omap_aes_dma_callback(int lch, u16 ch_status, void *data)
{
struct omap_aes_dev *dd = data;
@@ -271,13 +300,30 @@ static void omap_aes_dma_callback(int lch, u16 ch_status, void *data)
/* dma_lch_out - completed */
tasklet_schedule(&dd->done_task);
}
+#else
+static void omap_aes_dma_out_callback(void *data)
+{
+ struct omap_aes_dev *dd = data;
+
+ /* dma_lch_out - completed */
+ tasklet_schedule(&dd->done_task);
+}
+#endif

static int omap_aes_dma_init(struct omap_aes_dev *dd)
{
int err = -ENOMEM;
+#ifndef OMAP_AES_DMA_PRIVATE
+ dma_cap_mask_t mask;
+#endif

+#ifdef OMAP_AES_DMA_PRIVATE
dd->dma_lch_out = -1;
dd->dma_lch_in = -1;
+#else
+ dd->dma_lch_out = NULL;
+ dd->dma_lch_in = NULL;
+#endif

dd->buf_in = (void *)__get_free_pages(GFP_KERNEL, OMAP_AES_CACHE_SIZE);
dd->buf_out = (void *)__get_free_pages(GFP_KERNEL, OMAP_AES_CACHE_SIZE);
@@ -306,6 +352,7 @@ static int omap_aes_dma_init(struct omap_aes_dev *dd)
goto err_map_out;
}

+#ifdef OMAP_AES_DMA_PRIVATE
err = omap_request_dma(dd->dma_in, "omap-aes-rx",
omap_aes_dma_callback, dd, &dd->dma_lch_in);
if (err) {
@@ -318,11 +365,33 @@ static int omap_aes_dma_init(struct omap_aes_dev *dd)
dev_err(dd->dev, "Unable to request DMA channel\n");
goto err_dma_out;
}
+#else
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+
+ dd->dma_lch_in = dma_request_channel(mask, omap_dma_filter_fn,
+ &dd->dma_in);
+ if (!dd->dma_lch_in) {
+ dev_err(dd->dev, "Unable to request in DMA channel\n");
+ goto err_dma_in;
+ }
+
+ dd->dma_lch_out = dma_request_channel(mask, omap_dma_filter_fn,
+ &dd->dma_out);
+ if (!dd->dma_lch_out) {
+ dev_err(dd->dev, "Unable to request out DMA channel\n");
+ goto err_dma_out;
+ }
+#endif

return 0;

err_dma_out:
+#ifdef OMAP_AES_DMA_PRIVATE
omap_free_dma(dd->dma_lch_in);
+#else
+ dma_release_channel(dd->dma_lch_in);
+#endif
err_dma_in:
dma_unmap_single(dd->dev, dd->dma_addr_out, dd->buflen,
DMA_FROM_DEVICE);
@@ -339,8 +408,13 @@ err_alloc:

static void omap_aes_dma_cleanup(struct omap_aes_dev *dd)
{
+#ifdef OMAP_AES_DMA_PRIVATE
omap_free_dma(dd->dma_lch_out);
omap_free_dma(dd->dma_lch_in);
+#else
+ dma_release_channel(dd->dma_lch_out);
+ dma_release_channel(dd->dma_lch_in);
+#endif
dma_unmap_single(dd->dev, dd->dma_addr_out, dd->buflen,
DMA_FROM_DEVICE);
dma_unmap_single(dd->dev, dd->dma_addr_in, dd->buflen, DMA_TO_DEVICE);
@@ -398,12 +472,24 @@ static int sg_copy(struct scatterlist **sg, size_t *offset, void *buf,
return off;
}

+#ifdef OMAP_AES_DMA_PRIVATE
static int omap_aes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in,
dma_addr_t dma_addr_out, int length)
+#else
+static int omap_aes_crypt_dma(struct crypto_tfm *tfm,
+ struct scatterlist *in_sg, struct scatterlist *out_sg)
+#endif
{
struct omap_aes_ctx *ctx = crypto_tfm_ctx(tfm);
struct omap_aes_dev *dd = ctx->dd;
+#ifdef OMAP_AES_DMA_PRIVATE
int len32;
+#else
+ struct dma_async_tx_descriptor *tx_in, *tx_out;
+ struct dma_slave_config cfg;
+ dma_addr_t dma_addr_in = sg_dma_address(in_sg);
+ int ret, length = sg_dma_len(in_sg);
+#endif

pr_debug("len: %d\n", length);

@@ -413,6 +499,7 @@ static int omap_aes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in,
dma_sync_single_for_device(dd->dev, dma_addr_in, length,
DMA_TO_DEVICE);

+#ifdef OMAP_AES_DMA_PRIVATE
len32 = DIV_ROUND_UP(length, sizeof(u32));

/* IN */
@@ -433,6 +520,60 @@ static int omap_aes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in,

omap_start_dma(dd->dma_lch_in);
omap_start_dma(dd->dma_lch_out);
+#else
+ memset(&cfg, 0, sizeof(cfg));
+
+ cfg.src_addr = dd->phys_base + AES_REG_DATA;
+ cfg.dst_addr = dd->phys_base + AES_REG_DATA;
+ cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ cfg.src_maxburst = DST_MAXBURST;
+ cfg.dst_maxburst = DST_MAXBURST;
+
+ /* IN */
+ ret = dmaengine_slave_config(dd->dma_lch_in, &cfg);
+ if (ret) {
+ dev_err(dd->dev, "can't configure IN dmaengine slave: %d\n",
+ ret);
+ return ret;
+ }
+
+ tx_in = dmaengine_prep_slave_sg(dd->dma_lch_in, in_sg, 1,
+ DMA_MEM_TO_DEV,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!tx_in) {
+ dev_err(dd->dev, "IN prep_slave_sg() failed\n");
+ return -EINVAL;
+ }
+
+ /* No callback necessary */
+ tx_in->callback_param = dd;
+
+ /* OUT */
+ ret = dmaengine_slave_config(dd->dma_lch_out, &cfg);
+ if (ret) {
+ dev_err(dd->dev, "can't configure OUT dmaengine slave: %d\n",
+ ret);
+ return ret;
+ }
+
+ tx_out = dmaengine_prep_slave_sg(dd->dma_lch_out, out_sg, 1,
+ DMA_DEV_TO_MEM,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!tx_out) {
+ dev_err(dd->dev, "OUT prep_slave_sg() failed\n");
+ return -EINVAL;
+ }
+
+ tx_out->callback = omap_aes_dma_out_callback;
+ tx_out->callback_param = dd;
+
+ dmaengine_submit(tx_in);
+ dmaengine_submit(tx_out);
+
+ dma_async_issue_pending(dd->dma_lch_in);
+ dma_async_issue_pending(dd->dma_lch_out);
+#endif

/* start DMA or disable idle mode */
omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_START,
@@ -448,6 +589,10 @@ static int omap_aes_crypt_dma_start(struct omap_aes_dev *dd)
int err, fast = 0, in, out;
size_t count;
dma_addr_t addr_in, addr_out;
+#ifndef OMAP_AES_DMA_PRIVATE
+ struct scatterlist *in_sg, *out_sg;
+ int len32;
+#endif

pr_debug("total: %d\n", dd->total);

@@ -486,6 +631,11 @@ static int omap_aes_crypt_dma_start(struct omap_aes_dev *dd)
addr_in = sg_dma_address(dd->in_sg);
addr_out = sg_dma_address(dd->out_sg);

+#ifndef OMAP_AES_DMA_PRIVATE
+ in_sg = dd->in_sg;
+ out_sg = dd->out_sg;
+#endif
+
dd->flags |= FLAGS_FAST;

} else {
@@ -493,6 +643,29 @@ static int omap_aes_crypt_dma_start(struct omap_aes_dev *dd)
count = sg_copy(&dd->in_sg, &dd->in_offset, dd->buf_in,
dd->buflen, dd->total, 0);

+#ifndef OMAP_AES_DMA_PRIVATE
+ len32 = DIV_ROUND_UP(count, DMA_MIN) * DMA_MIN;
+
+ /*
+ * The data going into the AES module has been copied
+ * to a local buffer and the data coming out will go
+ * into a local buffer so set up local SG entries for
+ * both.
+ */
+ sg_init_table(&dd->in_sgl, 1);
+ dd->in_sgl.offset = dd->in_offset;
+ sg_dma_len(&dd->in_sgl) = len32;
+ sg_dma_address(&dd->in_sgl) = dd->dma_addr_in;
+
+ sg_init_table(&dd->out_sgl, 1);
+ dd->out_sgl.offset = dd->out_offset;
+ sg_dma_len(&dd->out_sgl) = len32;
+ sg_dma_address(&dd->out_sgl) = dd->dma_addr_out;
+
+ in_sg = &dd->in_sgl;
+ out_sg = &dd->out_sgl;
+#endif
+
addr_in = dd->dma_addr_in;
addr_out = dd->dma_addr_out;

@@ -502,7 +675,11 @@ static int omap_aes_crypt_dma_start(struct omap_aes_dev *dd)

dd->total -= count;

+#ifdef OMAP_AES_DMA_PRIVATE
err = omap_aes_crypt_dma(tfm, addr_in, addr_out, count);
+#else
+ err = omap_aes_crypt_dma(tfm, in_sg, out_sg);
+#endif
if (err) {
dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE);
dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_TO_DEVICE);
@@ -532,8 +709,13 @@ static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd)

omap_aes_write_mask(dd, AES_REG_MASK, 0, AES_REG_MASK_START);

+#ifdef OMAP_AES_DMA_PRIVATE
omap_stop_dma(dd->dma_lch_in);
omap_stop_dma(dd->dma_lch_out);
+#else
+ dmaengine_terminate_all(dd->dma_lch_in);
+ dmaengine_terminate_all(dd->dma_lch_out);
+#endif

if (dd->flags & FLAGS_FAST) {
dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_FROM_DEVICE);
--
1.7.12

2012-12-21 17:05:14

by Mark Greer

[permalink] [raw]
Subject: [PATCH 06/10] crypto: omap-aes - Remove usage of private DMA API

From: "Mark A. Greer" <[email protected]>

Remove usage of the private OMAP DMA API.
The dmaengine API will be used instead.

CC: Russell King <[email protected]>
CC: Dmitry Kasatkin <[email protected]>
Signed-off-by: Mark A. Greer <[email protected]>
---
drivers/crypto/omap-aes.c | 133 ----------------------------------------------
1 file changed, 133 deletions(-)

diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 14ec9e2..faf522f 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -12,8 +12,6 @@
*
*/

-#define OMAP_AES_DMA_PRIVATE
-
#define pr_fmt(fmt) "%s: " fmt, __func__

#include <linux/err.h>
@@ -115,33 +113,21 @@ struct omap_aes_dev {
struct ablkcipher_request *req;
size_t total;
struct scatterlist *in_sg;
-#ifndef OMAP_AES_DMA_PRIVATE
struct scatterlist in_sgl;
-#endif
size_t in_offset;
struct scatterlist *out_sg;
-#ifndef OMAP_AES_DMA_PRIVATE
struct scatterlist out_sgl;
-#endif
size_t out_offset;

size_t buflen;
void *buf_in;
size_t dma_size;
int dma_in;
-#ifdef OMAP_AES_DMA_PRIVATE
- int dma_lch_in;
-#else
struct dma_chan *dma_lch_in;
-#endif
dma_addr_t dma_addr_in;
void *buf_out;
int dma_out;
-#ifdef OMAP_AES_DMA_PRIVATE
- int dma_lch_out;
-#else
struct dma_chan *dma_lch_out;
-#endif
dma_addr_t dma_addr_out;
};

@@ -206,17 +192,10 @@ static int omap_aes_write_ctrl(struct omap_aes_dev *dd)
return err;

val = 0;
-#ifdef OMAP_AES_DMA_PRIVATE
- if (dd->dma_lch_out >= 0)
- val |= AES_REG_MASK_DMA_OUT_EN;
- if (dd->dma_lch_in >= 0)
- val |= AES_REG_MASK_DMA_IN_EN;
-#else
if (dd->dma_lch_out != NULL)
val |= AES_REG_MASK_DMA_OUT_EN;
if (dd->dma_lch_in != NULL)
val |= AES_REG_MASK_DMA_IN_EN;
-#endif

mask = AES_REG_MASK_DMA_IN_EN | AES_REG_MASK_DMA_OUT_EN;

@@ -244,22 +223,6 @@ static int omap_aes_write_ctrl(struct omap_aes_dev *dd)

omap_aes_write_mask(dd, AES_REG_CTRL, val, mask);

-#ifdef OMAP_AES_DMA_PRIVATE
- /* IN */
- omap_set_dma_dest_params(dd->dma_lch_in, 0, OMAP_DMA_AMODE_CONSTANT,
- dd->phys_base + AES_REG_DATA, 0, 4);
-
- omap_set_dma_dest_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4);
- omap_set_dma_src_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4);
-
- /* OUT */
- omap_set_dma_src_params(dd->dma_lch_out, 0, OMAP_DMA_AMODE_CONSTANT,
- dd->phys_base + AES_REG_DATA, 0, 4);
-
- omap_set_dma_src_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4);
- omap_set_dma_dest_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4);
-#endif
-
return 0;
}

@@ -284,23 +247,6 @@ static struct omap_aes_dev *omap_aes_find_dev(struct omap_aes_ctx *ctx)
return dd;
}

-#ifdef OMAP_AES_DMA_PRIVATE
-static void omap_aes_dma_callback(int lch, u16 ch_status, void *data)
-{
- struct omap_aes_dev *dd = data;
-
- if (ch_status != OMAP_DMA_BLOCK_IRQ) {
- pr_err("omap-aes DMA error status: 0x%hx\n", ch_status);
- dd->err = -EIO;
- dd->flags &= ~FLAGS_INIT; /* request to re-initialize */
- } else if (lch == dd->dma_lch_in) {
- return;
- }
-
- /* dma_lch_out - completed */
- tasklet_schedule(&dd->done_task);
-}
-#else
static void omap_aes_dma_out_callback(void *data)
{
struct omap_aes_dev *dd = data;
@@ -308,22 +254,14 @@ static void omap_aes_dma_out_callback(void *data)
/* dma_lch_out - completed */
tasklet_schedule(&dd->done_task);
}
-#endif

static int omap_aes_dma_init(struct omap_aes_dev *dd)
{
int err = -ENOMEM;
-#ifndef OMAP_AES_DMA_PRIVATE
dma_cap_mask_t mask;
-#endif

-#ifdef OMAP_AES_DMA_PRIVATE
- dd->dma_lch_out = -1;
- dd->dma_lch_in = -1;
-#else
dd->dma_lch_out = NULL;
dd->dma_lch_in = NULL;
-#endif

dd->buf_in = (void *)__get_free_pages(GFP_KERNEL, OMAP_AES_CACHE_SIZE);
dd->buf_out = (void *)__get_free_pages(GFP_KERNEL, OMAP_AES_CACHE_SIZE);
@@ -352,20 +290,6 @@ static int omap_aes_dma_init(struct omap_aes_dev *dd)
goto err_map_out;
}

-#ifdef OMAP_AES_DMA_PRIVATE
- err = omap_request_dma(dd->dma_in, "omap-aes-rx",
- omap_aes_dma_callback, dd, &dd->dma_lch_in);
- if (err) {
- dev_err(dd->dev, "Unable to request DMA channel\n");
- goto err_dma_in;
- }
- err = omap_request_dma(dd->dma_out, "omap-aes-tx",
- omap_aes_dma_callback, dd, &dd->dma_lch_out);
- if (err) {
- dev_err(dd->dev, "Unable to request DMA channel\n");
- goto err_dma_out;
- }
-#else
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);

@@ -382,16 +306,11 @@ static int omap_aes_dma_init(struct omap_aes_dev *dd)
dev_err(dd->dev, "Unable to request out DMA channel\n");
goto err_dma_out;
}
-#endif

return 0;

err_dma_out:
-#ifdef OMAP_AES_DMA_PRIVATE
- omap_free_dma(dd->dma_lch_in);
-#else
dma_release_channel(dd->dma_lch_in);
-#endif
err_dma_in:
dma_unmap_single(dd->dev, dd->dma_addr_out, dd->buflen,
DMA_FROM_DEVICE);
@@ -408,13 +327,8 @@ err_alloc:

static void omap_aes_dma_cleanup(struct omap_aes_dev *dd)
{
-#ifdef OMAP_AES_DMA_PRIVATE
- omap_free_dma(dd->dma_lch_out);
- omap_free_dma(dd->dma_lch_in);
-#else
dma_release_channel(dd->dma_lch_out);
dma_release_channel(dd->dma_lch_in);
-#endif
dma_unmap_single(dd->dev, dd->dma_addr_out, dd->buflen,
DMA_FROM_DEVICE);
dma_unmap_single(dd->dev, dd->dma_addr_in, dd->buflen, DMA_TO_DEVICE);
@@ -472,24 +386,15 @@ static int sg_copy(struct scatterlist **sg, size_t *offset, void *buf,
return off;
}

-#ifdef OMAP_AES_DMA_PRIVATE
-static int omap_aes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in,
- dma_addr_t dma_addr_out, int length)
-#else
static int omap_aes_crypt_dma(struct crypto_tfm *tfm,
struct scatterlist *in_sg, struct scatterlist *out_sg)
-#endif
{
struct omap_aes_ctx *ctx = crypto_tfm_ctx(tfm);
struct omap_aes_dev *dd = ctx->dd;
-#ifdef OMAP_AES_DMA_PRIVATE
- int len32;
-#else
struct dma_async_tx_descriptor *tx_in, *tx_out;
struct dma_slave_config cfg;
dma_addr_t dma_addr_in = sg_dma_address(in_sg);
int ret, length = sg_dma_len(in_sg);
-#endif

pr_debug("len: %d\n", length);

@@ -499,28 +404,6 @@ static int omap_aes_crypt_dma(struct crypto_tfm *tfm,
dma_sync_single_for_device(dd->dev, dma_addr_in, length,
DMA_TO_DEVICE);

-#ifdef OMAP_AES_DMA_PRIVATE
- len32 = DIV_ROUND_UP(length, sizeof(u32));
-
- /* IN */
- omap_set_dma_transfer_params(dd->dma_lch_in, OMAP_DMA_DATA_TYPE_S32,
- len32, 1, OMAP_DMA_SYNC_PACKET, dd->dma_in,
- OMAP_DMA_DST_SYNC);
-
- omap_set_dma_src_params(dd->dma_lch_in, 0, OMAP_DMA_AMODE_POST_INC,
- dma_addr_in, 0, 0);
-
- /* OUT */
- omap_set_dma_transfer_params(dd->dma_lch_out, OMAP_DMA_DATA_TYPE_S32,
- len32, 1, OMAP_DMA_SYNC_PACKET,
- dd->dma_out, OMAP_DMA_SRC_SYNC);
-
- omap_set_dma_dest_params(dd->dma_lch_out, 0, OMAP_DMA_AMODE_POST_INC,
- dma_addr_out, 0, 0);
-
- omap_start_dma(dd->dma_lch_in);
- omap_start_dma(dd->dma_lch_out);
-#else
memset(&cfg, 0, sizeof(cfg));

cfg.src_addr = dd->phys_base + AES_REG_DATA;
@@ -573,7 +456,6 @@ static int omap_aes_crypt_dma(struct crypto_tfm *tfm,

dma_async_issue_pending(dd->dma_lch_in);
dma_async_issue_pending(dd->dma_lch_out);
-#endif

/* start DMA or disable idle mode */
omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_START,
@@ -589,10 +471,8 @@ static int omap_aes_crypt_dma_start(struct omap_aes_dev *dd)
int err, fast = 0, in, out;
size_t count;
dma_addr_t addr_in, addr_out;
-#ifndef OMAP_AES_DMA_PRIVATE
struct scatterlist *in_sg, *out_sg;
int len32;
-#endif

pr_debug("total: %d\n", dd->total);

@@ -631,10 +511,8 @@ static int omap_aes_crypt_dma_start(struct omap_aes_dev *dd)
addr_in = sg_dma_address(dd->in_sg);
addr_out = sg_dma_address(dd->out_sg);

-#ifndef OMAP_AES_DMA_PRIVATE
in_sg = dd->in_sg;
out_sg = dd->out_sg;
-#endif

dd->flags |= FLAGS_FAST;

@@ -643,7 +521,6 @@ static int omap_aes_crypt_dma_start(struct omap_aes_dev *dd)
count = sg_copy(&dd->in_sg, &dd->in_offset, dd->buf_in,
dd->buflen, dd->total, 0);

-#ifndef OMAP_AES_DMA_PRIVATE
len32 = DIV_ROUND_UP(count, DMA_MIN) * DMA_MIN;

/*
@@ -664,7 +541,6 @@ static int omap_aes_crypt_dma_start(struct omap_aes_dev *dd)

in_sg = &dd->in_sgl;
out_sg = &dd->out_sgl;
-#endif

addr_in = dd->dma_addr_in;
addr_out = dd->dma_addr_out;
@@ -675,11 +551,7 @@ static int omap_aes_crypt_dma_start(struct omap_aes_dev *dd)

dd->total -= count;

-#ifdef OMAP_AES_DMA_PRIVATE
- err = omap_aes_crypt_dma(tfm, addr_in, addr_out, count);
-#else
err = omap_aes_crypt_dma(tfm, in_sg, out_sg);
-#endif
if (err) {
dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE);
dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_TO_DEVICE);
@@ -709,13 +581,8 @@ static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd)

omap_aes_write_mask(dd, AES_REG_MASK, 0, AES_REG_MASK_START);

-#ifdef OMAP_AES_DMA_PRIVATE
- omap_stop_dma(dd->dma_lch_in);
- omap_stop_dma(dd->dma_lch_out);
-#else
dmaengine_terminate_all(dd->dma_lch_in);
dmaengine_terminate_all(dd->dma_lch_out);
-#endif

if (dd->flags & FLAGS_FAST) {
dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_FROM_DEVICE);
--
1.7.12

2012-12-21 17:05:16

by Mark Greer

[permalink] [raw]
Subject: [PATCH 09/10] crypto: omap-aes - Add OMAP4/AM33XX AES Support

From: "Mark A. Greer" <[email protected]>

Add support for the OMAP4 version of the AES module
that is present on OMAP4 and AM33xx SoCs.

The modules have several differences including register
offsets and how DMA is triggered. To handle these
differences, a platform_data structure is defined and
contains routine pointers, register offsets, and bit
offsets within registers. OMAP2/OMAP3-specific routines
are suffixed with '_omap2' and OMAP4/AM33xx routines are
suffixed with '_omap4'.

Note: The code being integrated is from the TI AM33xx SDK
and was written by Greg Turner <[email protected]> and
Herman Schuurman (current email unknown) while at TI.

CC: Greg Turner <[email protected]>
CC: Dmitry Kasatkin <[email protected]>
Signed-off-by: Mark A. Greer <[email protected]>
---
drivers/crypto/omap-aes.c | 158 ++++++++++++++++++++++++++++++++++++----------
1 file changed, 125 insertions(+), 33 deletions(-)

diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index e28788e..b992f38 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -5,6 +5,7 @@
*
* Copyright (c) 2010 Nokia Corporation
* Author: Dmitry Kasatkin <[email protected]>
+ * Copyright (c) 2011 Texas Instruments Incorporated
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as published
@@ -42,10 +43,11 @@
#define FLD_MASK(start, end) (((1 << ((start) - (end) + 1)) - 1) << (end))
#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end))

-#define AES_REG_KEY(x) (0x1C - ((x ^ 0x01) * 0x04))
-#define AES_REG_IV(x) (0x20 + ((x) * 0x04))
+#define AES_REG_KEY(dd, x) ((dd)->pdata->key_ofs - \
+ ((x ^ 0x01) * 0x04))
+#define AES_REG_IV(dd, x) ((dd)->pdata->iv_ofs + ((x) * 0x04))

-#define AES_REG_CTRL 0x30
+#define AES_REG_CTRL(dd) ((dd)->pdata->ctrl_ofs)
#define AES_REG_CTRL_CTR_WIDTH (1 << 7)
#define AES_REG_CTRL_CTR (1 << 6)
#define AES_REG_CTRL_CBC (1 << 5)
@@ -54,14 +56,11 @@
#define AES_REG_CTRL_INPUT_READY (1 << 1)
#define AES_REG_CTRL_OUTPUT_READY (1 << 0)

-#define AES_REG_DATA 0x34
-#define AES_REG_DATA_N(x) (0x34 + ((x) * 0x04))
+#define AES_REG_DATA_N(dd, x) ((dd)->pdata->data_ofs + ((x) * 0x04))

-#define AES_REG_REV 0x44
-#define AES_REG_REV_MAJOR 0xF0
-#define AES_REG_REV_MINOR 0x0F
+#define AES_REG_REV(dd) ((dd)->pdata->rev_ofs)

-#define AES_REG_MASK 0x48
+#define AES_REG_MASK(dd) ((dd)->pdata->mask_ofs)
#define AES_REG_MASK_SIDLE (1 << 6)
#define AES_REG_MASK_START (1 << 5)
#define AES_REG_MASK_DMA_OUT_EN (1 << 3)
@@ -69,8 +68,7 @@
#define AES_REG_MASK_SOFTRESET (1 << 1)
#define AES_REG_AUTOIDLE (1 << 0)

-#define AES_REG_SYSSTATUS 0x4C
-#define AES_REG_SYSSTATUS_RESETDONE (1 << 0)
+#define AES_REG_LENGTH_N(x) (0x54 + ((x) * 0x04))

#define DEFAULT_TIMEOUT (5*HZ)

@@ -98,6 +96,26 @@ struct omap_aes_reqctx {
#define OMAP_AES_QUEUE_LENGTH 1
#define OMAP_AES_CACHE_SIZE 0

+struct omap_aes_pdata {
+ void (*trigger)(struct omap_aes_dev *dd, int length);
+
+ u32 key_ofs;
+ u32 iv_ofs;
+ u32 ctrl_ofs;
+ u32 data_ofs;
+ u32 rev_ofs;
+ u32 mask_ofs;
+
+ u32 dma_enable_in;
+ u32 dma_enable_out;
+ u32 dma_start;
+
+ u32 major_mask;
+ u32 major_shift;
+ u32 minor_mask;
+ u32 minor_shift;
+};
+
struct omap_aes_dev {
struct list_head list;
unsigned long phys_base;
@@ -132,6 +150,8 @@ struct omap_aes_dev {
int dma_out;
struct dma_chan *dma_lch_out;
dma_addr_t dma_addr_out;
+
+ const struct omap_aes_pdata *pdata;
};

/* keep registered devices data here */
@@ -194,26 +214,16 @@ static int omap_aes_write_ctrl(struct omap_aes_dev *dd)
if (err)
return err;

- val = 0;
- if (dd->dma_lch_out != NULL)
- val |= AES_REG_MASK_DMA_OUT_EN;
- if (dd->dma_lch_in != NULL)
- val |= AES_REG_MASK_DMA_IN_EN;
-
- mask = AES_REG_MASK_DMA_IN_EN | AES_REG_MASK_DMA_OUT_EN;
-
- omap_aes_write_mask(dd, AES_REG_MASK, val, mask);
-
key32 = dd->ctx->keylen / sizeof(u32);

/* it seems a key should always be set even if it has not changed */
for (i = 0; i < key32; i++) {
- omap_aes_write(dd, AES_REG_KEY(i),
+ omap_aes_write(dd, AES_REG_KEY(dd, i),
__le32_to_cpu(dd->ctx->key[i]));
}

if ((dd->flags & FLAGS_CBC) && dd->req->info)
- omap_aes_write_n(dd, AES_REG_IV(0), dd->req->info, 4);
+ omap_aes_write_n(dd, AES_REG_IV(dd, 0), dd->req->info, 4);

val = FLD_VAL(((dd->ctx->keylen >> 3) - 1), 4, 3);
if (dd->flags & FLAGS_CBC)
@@ -224,11 +234,47 @@ static int omap_aes_write_ctrl(struct omap_aes_dev *dd)
mask = AES_REG_CTRL_CBC | AES_REG_CTRL_DIRECTION |
AES_REG_CTRL_KEY_SIZE;

- omap_aes_write_mask(dd, AES_REG_CTRL, val, mask);
+ omap_aes_write_mask(dd, AES_REG_CTRL(dd), val, mask);

return 0;
}

+static void omap_aes_dma_trigger_omap2(struct omap_aes_dev *dd, int length)
+{
+ u32 mask, val;
+
+ val = dd->pdata->dma_start;
+
+ if (dd->dma_lch_out != NULL)
+ val |= dd->pdata->dma_enable_out;
+ if (dd->dma_lch_in != NULL)
+ val |= dd->pdata->dma_enable_in;
+
+ mask = dd->pdata->dma_enable_out | dd->pdata->dma_enable_in |
+ dd->pdata->dma_start;
+
+ omap_aes_write_mask(dd, AES_REG_MASK(dd), val, mask);
+
+}
+
+static void omap_aes_dma_trigger_omap4(struct omap_aes_dev *dd, int length)
+{
+ omap_aes_write(dd, AES_REG_LENGTH_N(0), length);
+ omap_aes_write(dd, AES_REG_LENGTH_N(1), 0);
+
+ omap_aes_dma_trigger_omap2(dd, length);
+}
+
+static void omap_aes_dma_stop(struct omap_aes_dev *dd)
+{
+ u32 mask;
+
+ mask = dd->pdata->dma_enable_out | dd->pdata->dma_enable_in |
+ dd->pdata->dma_start;
+
+ omap_aes_write_mask(dd, AES_REG_MASK(dd), 0, mask);
+}
+
static struct omap_aes_dev *omap_aes_find_dev(struct omap_aes_ctx *ctx)
{
struct omap_aes_dev *dd = NULL, *tmp;
@@ -413,8 +459,8 @@ static int omap_aes_crypt_dma(struct crypto_tfm *tfm,

memset(&cfg, 0, sizeof(cfg));

- cfg.src_addr = dd->phys_base + AES_REG_DATA;
- cfg.dst_addr = dd->phys_base + AES_REG_DATA;
+ cfg.src_addr = dd->phys_base + AES_REG_DATA_N(dd, 0);
+ cfg.dst_addr = dd->phys_base + AES_REG_DATA_N(dd, 0);
cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
cfg.src_maxburst = DST_MAXBURST;
@@ -464,9 +510,8 @@ static int omap_aes_crypt_dma(struct crypto_tfm *tfm,
dma_async_issue_pending(dd->dma_lch_in);
dma_async_issue_pending(dd->dma_lch_out);

- /* start DMA or disable idle mode */
- omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_START,
- AES_REG_MASK_START);
+ /* start DMA */
+ dd->pdata->trigger(dd, length);

return 0;
}
@@ -586,7 +631,7 @@ static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd)

pr_debug("total: %d\n", dd->total);

- omap_aes_write_mask(dd, AES_REG_MASK, 0, AES_REG_MASK_START);
+ omap_aes_dma_stop(dd);

dmaengine_terminate_all(dd->dma_lch_in);
dmaengine_terminate_all(dd->dma_lch_out);
@@ -826,10 +871,48 @@ static struct crypto_alg algs[] = {
}
};

+static const struct omap_aes_pdata omap_aes_pdata_omap2 = {
+ .trigger = omap_aes_dma_trigger_omap2,
+ .key_ofs = 0x1c,
+ .iv_ofs = 0x20,
+ .ctrl_ofs = 0x30,
+ .data_ofs = 0x34,
+ .rev_ofs = 0x44,
+ .mask_ofs = 0x48,
+ .dma_enable_in = BIT(2),
+ .dma_enable_out = BIT(3),
+ .dma_start = BIT(5),
+ .major_mask = 0xf0,
+ .major_shift = 4,
+ .minor_mask = 0x0f,
+ .minor_shift = 0,
+};
+
#ifdef CONFIG_OF
+static const struct omap_aes_pdata omap_aes_pdata_omap4 = {
+ .trigger = omap_aes_dma_trigger_omap4,
+ .key_ofs = 0x3c,
+ .iv_ofs = 0x40,
+ .ctrl_ofs = 0x50,
+ .data_ofs = 0x60,
+ .rev_ofs = 0x80,
+ .mask_ofs = 0x84,
+ .dma_enable_in = BIT(5),
+ .dma_enable_out = BIT(6),
+ .major_mask = 0x0700,
+ .major_shift = 8,
+ .minor_mask = 0x003f,
+ .minor_shift = 0,
+};
+
static const struct of_device_id omap_aes_of_match[] = {
{
.compatible = "ti,omap2-aes",
+ .data = &omap_aes_pdata_omap2,
+ },
+ {
+ .compatible = "ti,omap4-aes",
+ .data = &omap_aes_pdata_omap4,
},
{},
};
@@ -859,6 +942,8 @@ static int omap_aes_get_res_of(struct omap_aes_dev *dd,
dd->dma_out = -1; /* Dummy value that's unused */
dd->dma_in = -1; /* Dummy value that's unused */

+ dd->pdata = match->data;
+
err:
return err;
}
@@ -904,6 +989,9 @@ static int omap_aes_get_res_pdev(struct omap_aes_dev *dd,
}
dd->dma_in = r->start;

+ /* Only OMAP2/3 can be non-DT */
+ dd->pdata = &omap_aes_pdata_omap2;
+
err:
return err;
}
@@ -943,12 +1031,16 @@ static int omap_aes_probe(struct platform_device *pdev)
pm_runtime_enable(dev);
pm_runtime_get_sync(dev);

- reg = omap_aes_read(dd, AES_REG_REV);
- dev_info(dev, "OMAP AES hw accel rev: %u.%u\n",
- (reg & AES_REG_REV_MAJOR) >> 4, reg & AES_REG_REV_MINOR);
+ omap_aes_dma_stop(dd);
+
+ reg = omap_aes_read(dd, AES_REG_REV(dd));

pm_runtime_put_sync(dev);

+ dev_info(dev, "OMAP AES hw accel rev: %u.%u\n",
+ (reg & dd->pdata->major_mask) >> dd->pdata->major_shift,
+ (reg & dd->pdata->minor_mask) >> dd->pdata->minor_shift);
+
tasklet_init(&dd->done_task, omap_aes_done_task, (unsigned long)dd);
tasklet_init(&dd->queue_task, omap_aes_queue_task, (unsigned long)dd);

--
1.7.12

2012-12-21 17:05:17

by Mark Greer

[permalink] [raw]
Subject: [PATCH 10/10] crypto: omap-aes - Add CTR algorithm Support

From: "Mark A. Greer" <[email protected]>

The OMAP3 and OMAP4/AM33xx versions of the AES crypto
module support the CTR algorithm in addition to ECB
and CBC that the OMAP2 version of the module supports.

So, OMAP2 and OMAP3 share a common register set but
OMAP3 supports CTR while OMAP2 doesn't. OMAP4/AM33XX
uses a different register set from OMAP2/OMAP3 and
also supports CTR.

To add this support, use the platform_data introduced
in an ealier commit to hold the list of algorithms
supported by the current module. The probe routine
will use that list to register the correct algorithms.

Note: The code being integrated is from the TI AM33xx SDK
and was written by Greg Turner <[email protected]> and
Herman Schuurman (current email unknown) while at TI.

CC: Greg Turner <[email protected]>
CC: Dmitry Kasatkin <[email protected]>
Signed-off-by: Mark A. Greer <[email protected]>
---
drivers/crypto/omap-aes.c | 143 +++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 128 insertions(+), 15 deletions(-)

diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index b992f38..cf57866 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -48,7 +48,11 @@
#define AES_REG_IV(dd, x) ((dd)->pdata->iv_ofs + ((x) * 0x04))

#define AES_REG_CTRL(dd) ((dd)->pdata->ctrl_ofs)
-#define AES_REG_CTRL_CTR_WIDTH (1 << 7)
+#define AES_REG_CTRL_CTR_WIDTH_MASK (3 << 7)
+#define AES_REG_CTRL_CTR_WIDTH_32 (0 << 7)
+#define AES_REG_CTRL_CTR_WIDTH_64 (1 << 7)
+#define AES_REG_CTRL_CTR_WIDTH_96 (2 << 7)
+#define AES_REG_CTRL_CTR_WIDTH_128 (3 << 7)
#define AES_REG_CTRL_CTR (1 << 6)
#define AES_REG_CTRL_CBC (1 << 5)
#define AES_REG_CTRL_KEY_SIZE (3 << 3)
@@ -76,6 +80,7 @@
#define FLAGS_ENCRYPT BIT(0)
#define FLAGS_CBC BIT(1)
#define FLAGS_GIV BIT(2)
+#define FLAGS_CTR BIT(3)

#define FLAGS_INIT BIT(4)
#define FLAGS_FAST BIT(5)
@@ -96,7 +101,16 @@ struct omap_aes_reqctx {
#define OMAP_AES_QUEUE_LENGTH 1
#define OMAP_AES_CACHE_SIZE 0

+struct omap_aes_algs_info {
+ struct crypto_alg *algs_list;
+ unsigned int size;
+ unsigned int registered;
+};
+
struct omap_aes_pdata {
+ struct omap_aes_algs_info *algs_info;
+ unsigned int algs_info_size;
+
void (*trigger)(struct omap_aes_dev *dd, int length);

u32 key_ofs;
@@ -208,7 +222,7 @@ static int omap_aes_write_ctrl(struct omap_aes_dev *dd)
{
unsigned int key32;
int i, err;
- u32 val, mask;
+ u32 val, mask = 0;

err = omap_aes_hw_init(dd);
if (err)
@@ -222,16 +236,20 @@ static int omap_aes_write_ctrl(struct omap_aes_dev *dd)
__le32_to_cpu(dd->ctx->key[i]));
}

- if ((dd->flags & FLAGS_CBC) && dd->req->info)
+ if ((dd->flags & (FLAGS_CBC | FLAGS_CTR)) && dd->req->info)
omap_aes_write_n(dd, AES_REG_IV(dd, 0), dd->req->info, 4);

val = FLD_VAL(((dd->ctx->keylen >> 3) - 1), 4, 3);
if (dd->flags & FLAGS_CBC)
val |= AES_REG_CTRL_CBC;
+ if (dd->flags & FLAGS_CTR) {
+ val |= AES_REG_CTRL_CTR | AES_REG_CTRL_CTR_WIDTH_32;
+ mask = AES_REG_CTRL_CTR | AES_REG_CTRL_CTR_WIDTH_MASK;
+ }
if (dd->flags & FLAGS_ENCRYPT)
val |= AES_REG_CTRL_DIRECTION;

- mask = AES_REG_CTRL_CBC | AES_REG_CTRL_DIRECTION |
+ mask |= AES_REG_CTRL_CBC | AES_REG_CTRL_DIRECTION |
AES_REG_CTRL_KEY_SIZE;

omap_aes_write_mask(dd, AES_REG_CTRL(dd), val, mask);
@@ -807,6 +825,16 @@ static int omap_aes_cbc_decrypt(struct ablkcipher_request *req)
return omap_aes_crypt(req, FLAGS_CBC);
}

+static int omap_aes_ctr_encrypt(struct ablkcipher_request *req)
+{
+ return omap_aes_crypt(req, FLAGS_ENCRYPT | FLAGS_CTR);
+}
+
+static int omap_aes_ctr_decrypt(struct ablkcipher_request *req)
+{
+ return omap_aes_crypt(req, FLAGS_CTR);
+}
+
static int omap_aes_cra_init(struct crypto_tfm *tfm)
{
pr_debug("enter\n");
@@ -823,7 +851,7 @@ static void omap_aes_cra_exit(struct crypto_tfm *tfm)

/* ********************** ALGS ************************************ */

-static struct crypto_alg algs[] = {
+static struct crypto_alg algs_ecb_cbc[] = {
{
.cra_name = "ecb(aes)",
.cra_driver_name = "ecb-aes-omap",
@@ -871,7 +899,43 @@ static struct crypto_alg algs[] = {
}
};

+static struct crypto_alg algs_ctr[] = {
+{
+ .cra_name = "ctr(aes)",
+ .cra_driver_name = "ctr-aes-omap",
+ .cra_priority = 100,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
+ CRYPTO_ALG_KERN_DRIVER_ONLY |
+ CRYPTO_ALG_ASYNC,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct omap_aes_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_init = omap_aes_cra_init,
+ .cra_exit = omap_aes_cra_exit,
+ .cra_u.ablkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .geniv = "eseqiv",
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = omap_aes_setkey,
+ .encrypt = omap_aes_ctr_encrypt,
+ .decrypt = omap_aes_ctr_decrypt,
+ }
+} ,
+};
+
+static struct omap_aes_algs_info omap_aes_algs_info_ecb_cbc[] = {
+ {
+ .algs_list = algs_ecb_cbc,
+ .size = ARRAY_SIZE(algs_ecb_cbc),
+ },
+};
+
static const struct omap_aes_pdata omap_aes_pdata_omap2 = {
+ .algs_info = omap_aes_algs_info_ecb_cbc,
+ .algs_info_size = ARRAY_SIZE(omap_aes_algs_info_ecb_cbc),
.trigger = omap_aes_dma_trigger_omap2,
.key_ofs = 0x1c,
.iv_ofs = 0x20,
@@ -889,7 +953,39 @@ static const struct omap_aes_pdata omap_aes_pdata_omap2 = {
};

#ifdef CONFIG_OF
+static struct omap_aes_algs_info omap_aes_algs_info_ecb_cbc_ctr[] = {
+ {
+ .algs_list = algs_ecb_cbc,
+ .size = ARRAY_SIZE(algs_ecb_cbc),
+ },
+ {
+ .algs_list = algs_ctr,
+ .size = ARRAY_SIZE(algs_ctr),
+ },
+};
+
+static const struct omap_aes_pdata omap_aes_pdata_omap3 = {
+ .algs_info = omap_aes_algs_info_ecb_cbc_ctr,
+ .algs_info_size = ARRAY_SIZE(omap_aes_algs_info_ecb_cbc_ctr),
+ .trigger = omap_aes_dma_trigger_omap2,
+ .key_ofs = 0x1c,
+ .iv_ofs = 0x20,
+ .ctrl_ofs = 0x30,
+ .data_ofs = 0x34,
+ .rev_ofs = 0x44,
+ .mask_ofs = 0x48,
+ .dma_enable_in = BIT(2),
+ .dma_enable_out = BIT(3),
+ .dma_start = BIT(5),
+ .major_mask = 0xf0,
+ .major_shift = 4,
+ .minor_mask = 0x0f,
+ .minor_shift = 0,
+};
+
static const struct omap_aes_pdata omap_aes_pdata_omap4 = {
+ .algs_info = omap_aes_algs_info_ecb_cbc_ctr,
+ .algs_info_size = ARRAY_SIZE(omap_aes_algs_info_ecb_cbc_ctr),
.trigger = omap_aes_dma_trigger_omap4,
.key_ofs = 0x3c,
.iv_ofs = 0x40,
@@ -911,6 +1007,10 @@ static const struct of_device_id omap_aes_of_match[] = {
.data = &omap_aes_pdata_omap2,
},
{
+ .compatible = "ti,omap3-aes",
+ .data = &omap_aes_pdata_omap3,
+ },
+ {
.compatible = "ti,omap4-aes",
.data = &omap_aes_pdata_omap4,
},
@@ -1000,6 +1100,7 @@ static int omap_aes_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct omap_aes_dev *dd;
+ struct crypto_alg *algp;
struct resource res;
int err = -ENOMEM, i, j;
u32 reg;
@@ -1053,17 +1154,27 @@ static int omap_aes_probe(struct platform_device *pdev)
list_add_tail(&dd->list, &dev_list);
spin_unlock(&list_lock);

- for (i = 0; i < ARRAY_SIZE(algs); i++) {
- pr_debug("i: %d\n", i);
- err = crypto_register_alg(&algs[i]);
- if (err)
- goto err_algs;
+ for (i = 0; i < dd->pdata->algs_info_size; i++) {
+ for (j = 0; j < dd->pdata->algs_info[i].size; j++) {
+ algp = &dd->pdata->algs_info[i].algs_list[j];
+
+ pr_debug("reg alg: %s\n", algp->cra_name);
+ INIT_LIST_HEAD(&algp->cra_list);
+
+ err = crypto_register_alg(algp);
+ if (err)
+ goto err_algs;
+
+ dd->pdata->algs_info[i].registered++;
+ }
}

return 0;
err_algs:
- for (j = 0; j < i; j++)
- crypto_unregister_alg(&algs[j]);
+ for (i = dd->pdata->algs_info_size - 1; i >= 0; i--)
+ for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--)
+ crypto_unregister_alg(
+ &dd->pdata->algs_info[i].algs_list[j]);
omap_aes_dma_cleanup(dd);
err_dma:
tasklet_kill(&dd->done_task);
@@ -1080,7 +1191,7 @@ err_data:
static int omap_aes_remove(struct platform_device *pdev)
{
struct omap_aes_dev *dd = platform_get_drvdata(pdev);
- int i;
+ int i, j;

if (!dd)
return -ENODEV;
@@ -1089,8 +1200,10 @@ static int omap_aes_remove(struct platform_device *pdev)
list_del(&dd->list);
spin_unlock(&list_lock);

- for (i = 0; i < ARRAY_SIZE(algs); i++)
- crypto_unregister_alg(&algs[i]);
+ for (i = dd->pdata->algs_info_size - 1; i >= 0; i--)
+ for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--)
+ crypto_unregister_alg(
+ &dd->pdata->algs_info[i].algs_list[j]);

tasklet_kill(&dd->done_task);
tasklet_kill(&dd->queue_task);
--
1.7.12

2012-12-28 10:06:02

by Russ Dill

[permalink] [raw]
Subject: Re: [PATCH 07/10] crypto: omap-aes - Add Device Tree Support

On Fri, Dec 21, 2012 at 10:04 AM, Mark A. Greer <[email protected]> wrote:
> From: "Mark A. Greer" <[email protected]>
>
> Add Device Tree suport to the omap-aes crypto
> driver. Currently, only support for OMAP2 and
> OMAP3 is being added but support for OMAP4 will
> be added in a subsequent patch.
>
> CC: Dmitry Kasatkin <[email protected]>
> Signed-off-by: Mark A. Greer <[email protected]>
> ---
> drivers/crypto/omap-aes.c | 119 ++++++++++++++++++++++++++++++++++++----------
> 1 file changed, 93 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
> index faf522f..68bf22d 100644
> --- a/drivers/crypto/omap-aes.c
> +++ b/drivers/crypto/omap-aes.c
> @@ -25,6 +25,9 @@
> #include <linux/dmaengine.h>
> #include <linux/omap-dma.h>
> #include <linux/pm_runtime.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/of_address.h>
> #include <linux/io.h>
> #include <linux/crypto.h>
> #include <linux/interrupt.h>
> @@ -819,11 +822,93 @@ static struct crypto_alg algs[] = {
> }
> };
>
> +#ifdef CONFIG_OF
> +static const struct of_device_id omap_aes_of_match[] = {
> + {
> + .compatible = "ti,omap2-aes",
> + },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, omap_aes_of_match);

I think you mean for the above section to be outside of the '#ifdef
CONFIG_OF' block.

> +static int omap_aes_get_res_of(struct omap_aes_dev *dd,
> + struct device *dev, struct resource *res)
> +{
> + struct device_node *node = dev->of_node;
> + const struct of_device_id *match;
> + int err = 0;
> +
> + match = of_match_device(of_match_ptr(omap_aes_of_match), dev);
> + if (!match) {
> + dev_err(dev, "no compatible OF match\n");
> + err = -EINVAL;
> + goto err;
> + }
> +
> + err = of_address_to_resource(node, 0, res);
> + if (err < 0) {
> + dev_err(dev, "can't translate OF node address\n");
> + err = -EINVAL;
> + goto err;
> + }
> +
> + dd->dma_out = -1; /* Dummy value that's unused */
> + dd->dma_in = -1; /* Dummy value that's unused */
> +
> +err:
> + return err;
> +}
> +#else
> +static int omap_aes_get_res_dev(struct omap_aes_dev *dd,
> + struct device *dev, struct resource *res)
> +{
> + return -EINVAL;
> +}

And I think you mean this one to be omap_aes_get_res_of

> +#endif
> +
> +static int omap_aes_get_res_pdev(struct omap_aes_dev *dd,
> + struct platform_device *pdev, struct resource *res)
> +{
> + struct device *dev = &pdev->dev;
> + struct resource *r;
> + int err = 0;
> +
> + /* Get the base address */
> + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + if (!r) {
> + dev_err(dev, "no MEM resource info\n");
> + err = -ENODEV;
> + goto err;
> + }
> + memcpy(res, r, sizeof(*res));
> +
> + /* Get the DMA out channel */
> + r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
> + if (!r) {
> + dev_err(dev, "no DMA out resource info\n");
> + err = -ENODEV;
> + goto err;
> + }
> + dd->dma_out = r->start;
> +
> + /* Get the DMA in channel */
> + r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
> + if (!r) {
> + dev_err(dev, "no DMA in resource info\n");
> + err = -ENODEV;
> + goto err;
> + }
> + dd->dma_in = r->start;
> +
> +err:
> + return err;
> +}
> +
> static int omap_aes_probe(struct platform_device *pdev)
> {
> struct device *dev = &pdev->dev;
> struct omap_aes_dev *dd;
> - struct resource *res;
> + struct resource res;
> int err = -ENOMEM, i, j;
> u32 reg;
>
> @@ -838,35 +923,18 @@ static int omap_aes_probe(struct platform_device *pdev)
> spin_lock_init(&dd->lock);
> crypto_init_queue(&dd->queue, OMAP_AES_QUEUE_LENGTH);
>
> - /* Get the base address */
> - res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> - if (!res) {
> - dev_err(dev, "invalid resource type\n");
> - err = -ENODEV;
> + err = (dev->of_node) ? omap_aes_get_res_of(dd, dev, &res) :
> + omap_aes_get_res_pdev(dd, pdev, &res);
> + if (err)
> goto err_res;
> - }
> - dd->phys_base = res->start;
> -
> - /* Get the DMA */
> - res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
> - if (!res)
> - dev_info(dev, "no DMA info\n");
> - else
> - dd->dma_out = res->start;
> -
> - /* Get the DMA */
> - res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
> - if (!res)
> - dev_info(dev, "no DMA info\n");
> - else
> - dd->dma_in = res->start;
> -
> - dd->io_base = ioremap(dd->phys_base, SZ_4K);
> +
> + dd->io_base = devm_request_and_ioremap(dev, &res);
> if (!dd->io_base) {
> dev_err(dev, "can't ioremap\n");
> err = -ENOMEM;
> goto err_res;
> }
> + dd->phys_base = res.start;
>
> pm_runtime_enable(dev);
> pm_runtime_get_sync(dev);
> @@ -904,7 +972,6 @@ err_algs:
> err_dma:
> tasklet_kill(&dd->done_task);
> tasklet_kill(&dd->queue_task);
> - iounmap(dd->io_base);
> pm_runtime_disable(dev);
> err_res:
> kfree(dd);
> @@ -932,7 +999,6 @@ static int omap_aes_remove(struct platform_device *pdev)
> tasklet_kill(&dd->done_task);
> tasklet_kill(&dd->queue_task);
> omap_aes_dma_cleanup(dd);
> - iounmap(dd->io_base);
> pm_runtime_disable(dd->dev);
> kfree(dd);
> dd = NULL;
> @@ -965,6 +1031,7 @@ static struct platform_driver omap_aes_driver = {
> .name = "omap-aes",
> .owner = THIS_MODULE,
> .pm = &omap_aes_pm_ops,
> + .of_match_table = omap_aes_of_match,
> },
> };
>
> --
> 1.7.12
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html

2013-01-07 23:29:50

by Mark Greer

[permalink] [raw]
Subject: Re: [PATCH 07/10] crypto: omap-aes - Add Device Tree Support

On Fri, Dec 28, 2012 at 02:06:02AM -0800, Russ Dill wrote:
> On Fri, Dec 21, 2012 at 10:04 AM, Mark A. Greer <[email protected]> wrote:
> > From: "Mark A. Greer" <[email protected]>
> >
> > Add Device Tree suport to the omap-aes crypto
> > driver. Currently, only support for OMAP2 and
> > OMAP3 is being added but support for OMAP4 will
> > be added in a subsequent patch.
> >
> > CC: Dmitry Kasatkin <[email protected]>
> > Signed-off-by: Mark A. Greer <[email protected]>
> > ---
> > drivers/crypto/omap-aes.c | 119 ++++++++++++++++++++++++++++++++++++----------
> > 1 file changed, 93 insertions(+), 26 deletions(-)
> >
> > diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
> > index faf522f..68bf22d 100644
> > --- a/drivers/crypto/omap-aes.c
> > +++ b/drivers/crypto/omap-aes.c
> > @@ -25,6 +25,9 @@
> > #include <linux/dmaengine.h>
> > #include <linux/omap-dma.h>
> > #include <linux/pm_runtime.h>
> > +#include <linux/of.h>
> > +#include <linux/of_device.h>
> > +#include <linux/of_address.h>
> > #include <linux/io.h>
> > #include <linux/crypto.h>
> > #include <linux/interrupt.h>
> > @@ -819,11 +822,93 @@ static struct crypto_alg algs[] = {
> > }
> > };
> >
> > +#ifdef CONFIG_OF
> > +static const struct of_device_id omap_aes_of_match[] = {
> > + {
> > + .compatible = "ti,omap2-aes",
> > + },
> > + {},
> > +};
> > +MODULE_DEVICE_TABLE(of, omap_aes_of_match);
>
> I think you mean for the above section to be outside of the '#ifdef
> CONFIG_OF' block.

Yes, I need to rework that.

> > +static int omap_aes_get_res_of(struct omap_aes_dev *dd,
> > + struct device *dev, struct resource *res)
> > +{
> > + struct device_node *node = dev->of_node;
> > + const struct of_device_id *match;
> > + int err = 0;
> > +
> > + match = of_match_device(of_match_ptr(omap_aes_of_match), dev);
> > + if (!match) {
> > + dev_err(dev, "no compatible OF match\n");
> > + err = -EINVAL;
> > + goto err;
> > + }
> > +
> > + err = of_address_to_resource(node, 0, res);
> > + if (err < 0) {
> > + dev_err(dev, "can't translate OF node address\n");
> > + err = -EINVAL;
> > + goto err;
> > + }
> > +
> > + dd->dma_out = -1; /* Dummy value that's unused */
> > + dd->dma_in = -1; /* Dummy value that's unused */
> > +
> > +err:
> > + return err;
> > +}
> > +#else
> > +static int omap_aes_get_res_dev(struct omap_aes_dev *dd,
> > + struct device *dev, struct resource *res)
> > +{
> > + return -EINVAL;
> > +}
>
> And I think you mean this one to be omap_aes_get_res_of

I do. :(

Thanks Russ.

Mark
--

2013-01-08 19:06:34

by Mark Greer

[permalink] [raw]
Subject: Re: [PATCH 07/10] crypto: omap-aes - Add Device Tree Support

On Fri, Dec 28, 2012 at 02:06:02AM -0800, Russ Dill wrote:
> On Fri, Dec 21, 2012 at 10:04 AM, Mark A. Greer <[email protected]> wrote:
> > From: "Mark A. Greer" <[email protected]>
> >
> > Add Device Tree suport to the omap-aes crypto
> > driver. Currently, only support for OMAP2 and
> > OMAP3 is being added but support for OMAP4 will
> > be added in a subsequent patch.
> >
> > CC: Dmitry Kasatkin <[email protected]>
> > Signed-off-by: Mark A. Greer <[email protected]>
> > ---
> > drivers/crypto/omap-aes.c | 119 ++++++++++++++++++++++++++++++++++++----------
> > 1 file changed, 93 insertions(+), 26 deletions(-)
> >
> > diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
> > index faf522f..68bf22d 100644
> > --- a/drivers/crypto/omap-aes.c
> > +++ b/drivers/crypto/omap-aes.c
> > @@ -25,6 +25,9 @@
> > #include <linux/dmaengine.h>
> > #include <linux/omap-dma.h>
> > #include <linux/pm_runtime.h>
> > +#include <linux/of.h>
> > +#include <linux/of_device.h>
> > +#include <linux/of_address.h>
> > #include <linux/io.h>
> > #include <linux/crypto.h>
> > #include <linux/interrupt.h>
> > @@ -819,11 +822,93 @@ static struct crypto_alg algs[] = {
> > }
> > };
> >
> > +#ifdef CONFIG_OF
> > +static const struct of_device_id omap_aes_of_match[] = {
> > + {
> > + .compatible = "ti,omap2-aes",
> > + },
> > + {},
> > +};
> > +MODULE_DEVICE_TABLE(of, omap_aes_of_match);
>
> I think you mean for the above section to be outside of the '#ifdef
> CONFIG_OF' block.
>
> > +static int omap_aes_get_res_of(struct omap_aes_dev *dd,
> > + struct device *dev, struct resource *res)
> > +{
> > + struct device_node *node = dev->of_node;
> > + const struct of_device_id *match;
> > + int err = 0;
> > +
> > + match = of_match_device(of_match_ptr(omap_aes_of_match), dev);
> > + if (!match) {
> > + dev_err(dev, "no compatible OF match\n");
> > + err = -EINVAL;
> > + goto err;
> > + }
> > +
> > + err = of_address_to_resource(node, 0, res);
> > + if (err < 0) {
> > + dev_err(dev, "can't translate OF node address\n");
> > + err = -EINVAL;
> > + goto err;
> > + }
> > +
> > + dd->dma_out = -1; /* Dummy value that's unused */
> > + dd->dma_in = -1; /* Dummy value that's unused */
> > +
> > +err:
> > + return err;
> > +}
> > +#else
> > +static int omap_aes_get_res_dev(struct omap_aes_dev *dd,
> > + struct device *dev, struct resource *res)
> > +{
> > + return -EINVAL;
> > +}
>
> And I think you mean this one to be omap_aes_get_res_of

Your comments should be addressed in v2 of this series,

http://www.spinics.net/lists/linux-omap/msg84629.html

Mark
--