aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto
diff options
context:
space:
mode:
authorNicolas Ferre <nicolas.ferre@atmel.com>2013-10-14 11:52:38 -0400
committerNicolas Ferre <nicolas.ferre@atmel.com>2013-12-12 12:39:35 -0500
commitbe943c7d27b14dbd700770d2fd6c704be95a0ec9 (patch)
tree4e8b9085698a10873ce91f646f5d13684b97357c /drivers/crypto
parentb46e837d8ef1f3c777bbf9513e2cdb5d87d6c374 (diff)
crypto: atmel-aes - add support for Device Tree
Add support for Device Tree and use of the DMA DT API to get the needed channels. Documentation is added for these DT nodes. Initial code by: Nicolas Royer and Eukrea. Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com> Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto')
-rw-r--r--drivers/crypto/atmel-aes.c143
1 files changed, 94 insertions, 49 deletions
diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c
index c1efd910d97b..d7c9e317423c 100644
--- a/drivers/crypto/atmel-aes.c
+++ b/drivers/crypto/atmel-aes.c
@@ -30,6 +30,7 @@
30#include <linux/irq.h> 30#include <linux/irq.h>
31#include <linux/scatterlist.h> 31#include <linux/scatterlist.h>
32#include <linux/dma-mapping.h> 32#include <linux/dma-mapping.h>
33#include <linux/of_device.h>
33#include <linux/delay.h> 34#include <linux/delay.h>
34#include <linux/crypto.h> 35#include <linux/crypto.h>
35#include <linux/cryptohash.h> 36#include <linux/cryptohash.h>
@@ -39,6 +40,7 @@
39#include <crypto/hash.h> 40#include <crypto/hash.h>
40#include <crypto/internal/hash.h> 41#include <crypto/internal/hash.h>
41#include <linux/platform_data/crypto-atmel.h> 42#include <linux/platform_data/crypto-atmel.h>
43#include <dt-bindings/dma/at91.h>
42#include "atmel-aes-regs.h" 44#include "atmel-aes-regs.h"
43 45
44#define CFB8_BLOCK_SIZE 1 46#define CFB8_BLOCK_SIZE 1
@@ -747,59 +749,50 @@ static int atmel_aes_dma_init(struct atmel_aes_dev *dd,
747 struct crypto_platform_data *pdata) 749 struct crypto_platform_data *pdata)
748{ 750{
749 int err = -ENOMEM; 751 int err = -ENOMEM;
750 dma_cap_mask_t mask_in, mask_out; 752 dma_cap_mask_t mask;
753
754 dma_cap_zero(mask);
755 dma_cap_set(DMA_SLAVE, mask);
756
757 /* Try to grab 2 DMA channels */
758 dd->dma_lch_in.chan = dma_request_slave_channel_compat(mask,
759 atmel_aes_filter, &pdata->dma_slave->rxdata, dd->dev, "tx");
760 if (!dd->dma_lch_in.chan)
761 goto err_dma_in;
762
763 dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV;
764 dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base +
765 AES_IDATAR(0);
766 dd->dma_lch_in.dma_conf.src_maxburst = dd->caps.max_burst_size;
767 dd->dma_lch_in.dma_conf.src_addr_width =
768 DMA_SLAVE_BUSWIDTH_4_BYTES;
769 dd->dma_lch_in.dma_conf.dst_maxburst = dd->caps.max_burst_size;
770 dd->dma_lch_in.dma_conf.dst_addr_width =
771 DMA_SLAVE_BUSWIDTH_4_BYTES;
772 dd->dma_lch_in.dma_conf.device_fc = false;
773
774 dd->dma_lch_out.chan = dma_request_slave_channel_compat(mask,
775 atmel_aes_filter, &pdata->dma_slave->txdata, dd->dev, "rx");
776 if (!dd->dma_lch_out.chan)
777 goto err_dma_out;
778
779 dd->dma_lch_out.dma_conf.direction = DMA_DEV_TO_MEM;
780 dd->dma_lch_out.dma_conf.src_addr = dd->phys_base +
781 AES_ODATAR(0);
782 dd->dma_lch_out.dma_conf.src_maxburst = dd->caps.max_burst_size;
783 dd->dma_lch_out.dma_conf.src_addr_width =
784 DMA_SLAVE_BUSWIDTH_4_BYTES;
785 dd->dma_lch_out.dma_conf.dst_maxburst = dd->caps.max_burst_size;
786 dd->dma_lch_out.dma_conf.dst_addr_width =
787 DMA_SLAVE_BUSWIDTH_4_BYTES;
788 dd->dma_lch_out.dma_conf.device_fc = false;
751 789
752 if (pdata && pdata->dma_slave->txdata.dma_dev && 790 return 0;
753 pdata->dma_slave->rxdata.dma_dev) {
754
755 /* Try to grab 2 DMA channels */
756 dma_cap_zero(mask_in);
757 dma_cap_set(DMA_SLAVE, mask_in);
758
759 dd->dma_lch_in.chan = dma_request_channel(mask_in,
760 atmel_aes_filter, &pdata->dma_slave->rxdata);
761
762 if (!dd->dma_lch_in.chan)
763 goto err_dma_in;
764
765 dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV;
766 dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base +
767 AES_IDATAR(0);
768 dd->dma_lch_in.dma_conf.src_maxburst = dd->caps.max_burst_size;
769 dd->dma_lch_in.dma_conf.src_addr_width =
770 DMA_SLAVE_BUSWIDTH_4_BYTES;
771 dd->dma_lch_in.dma_conf.dst_maxburst = dd->caps.max_burst_size;
772 dd->dma_lch_in.dma_conf.dst_addr_width =
773 DMA_SLAVE_BUSWIDTH_4_BYTES;
774 dd->dma_lch_in.dma_conf.device_fc = false;
775
776 dma_cap_zero(mask_out);
777 dma_cap_set(DMA_SLAVE, mask_out);
778 dd->dma_lch_out.chan = dma_request_channel(mask_out,
779 atmel_aes_filter, &pdata->dma_slave->txdata);
780
781 if (!dd->dma_lch_out.chan)
782 goto err_dma_out;
783
784 dd->dma_lch_out.dma_conf.direction = DMA_DEV_TO_MEM;
785 dd->dma_lch_out.dma_conf.src_addr = dd->phys_base +
786 AES_ODATAR(0);
787 dd->dma_lch_out.dma_conf.src_maxburst = dd->caps.max_burst_size;
788 dd->dma_lch_out.dma_conf.src_addr_width =
789 DMA_SLAVE_BUSWIDTH_4_BYTES;
790 dd->dma_lch_out.dma_conf.dst_maxburst = dd->caps.max_burst_size;
791 dd->dma_lch_out.dma_conf.dst_addr_width =
792 DMA_SLAVE_BUSWIDTH_4_BYTES;
793 dd->dma_lch_out.dma_conf.device_fc = false;
794
795 return 0;
796 } else {
797 return -ENODEV;
798 }
799 791
800err_dma_out: 792err_dma_out:
801 dma_release_channel(dd->dma_lch_in.chan); 793 dma_release_channel(dd->dma_lch_in.chan);
802err_dma_in: 794err_dma_in:
795 dev_warn(dd->dev, "no DMA channel available\n");
803 return err; 796 return err;
804} 797}
805 798
@@ -1261,6 +1254,47 @@ static void atmel_aes_get_cap(struct atmel_aes_dev *dd)
1261 } 1254 }
1262} 1255}
1263 1256
1257#if defined(CONFIG_OF)
1258static const struct of_device_id atmel_aes_dt_ids[] = {
1259 { .compatible = "atmel,at91sam9g46-aes" },
1260 { /* sentinel */ }
1261};
1262MODULE_DEVICE_TABLE(of, atmel_aes_dt_ids);
1263
1264static struct crypto_platform_data *atmel_aes_of_init(struct platform_device *pdev)
1265{
1266 struct device_node *np = pdev->dev.of_node;
1267 struct crypto_platform_data *pdata;
1268
1269 if (!np) {
1270 dev_err(&pdev->dev, "device node not found\n");
1271 return ERR_PTR(-EINVAL);
1272 }
1273
1274 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
1275 if (!pdata) {
1276 dev_err(&pdev->dev, "could not allocate memory for pdata\n");
1277 return ERR_PTR(-ENOMEM);
1278 }
1279
1280 pdata->dma_slave = devm_kzalloc(&pdev->dev,
1281 sizeof(*(pdata->dma_slave)),
1282 GFP_KERNEL);
1283 if (!pdata->dma_slave) {
1284 dev_err(&pdev->dev, "could not allocate memory for dma_slave\n");
1285 devm_kfree(&pdev->dev, pdata);
1286 return ERR_PTR(-ENOMEM);
1287 }
1288
1289 return pdata;
1290}
1291#else
1292static inline struct crypto_platform_data *atmel_aes_of_init(struct platform_device *pdev)
1293{
1294 return ERR_PTR(-EINVAL);
1295}
1296#endif
1297
1264static int atmel_aes_probe(struct platform_device *pdev) 1298static int atmel_aes_probe(struct platform_device *pdev)
1265{ 1299{
1266 struct atmel_aes_dev *aes_dd; 1300 struct atmel_aes_dev *aes_dd;
@@ -1272,6 +1306,14 @@ static int atmel_aes_probe(struct platform_device *pdev)
1272 1306
1273 pdata = pdev->dev.platform_data; 1307 pdata = pdev->dev.platform_data;
1274 if (!pdata) { 1308 if (!pdata) {
1309 pdata = atmel_aes_of_init(pdev);
1310 if (IS_ERR(pdata)) {
1311 err = PTR_ERR(pdata);
1312 goto aes_dd_err;
1313 }
1314 }
1315
1316 if (!pdata->dma_slave) {
1275 err = -ENXIO; 1317 err = -ENXIO;
1276 goto aes_dd_err; 1318 goto aes_dd_err;
1277 } 1319 }
@@ -1358,7 +1400,9 @@ static int atmel_aes_probe(struct platform_device *pdev)
1358 if (err) 1400 if (err)
1359 goto err_algs; 1401 goto err_algs;
1360 1402
1361 dev_info(dev, "Atmel AES\n"); 1403 dev_info(dev, "Atmel AES - Using %s, %s for DMA transfers\n",
1404 dma_chan_name(aes_dd->dma_lch_in.chan),
1405 dma_chan_name(aes_dd->dma_lch_out.chan));
1362 1406
1363 return 0; 1407 return 0;
1364 1408
@@ -1424,6 +1468,7 @@ static struct platform_driver atmel_aes_driver = {
1424 .driver = { 1468 .driver = {
1425 .name = "atmel_aes", 1469 .name = "atmel_aes",
1426 .owner = THIS_MODULE, 1470 .owner = THIS_MODULE,
1471 .of_match_table = of_match_ptr(atmel_aes_dt_ids),
1427 }, 1472 },
1428}; 1473};
1429 1474