diff options
author | Olof Johansson <olof@lixom.net> | 2013-12-22 14:42:50 -0500 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2013-12-22 14:42:50 -0500 |
commit | 8f2d751a9e4061f30e10a38ef2da81552239da3e (patch) | |
tree | cea719ff0474b0b693d59db662102fddfa98be57 /drivers/crypto | |
parent | 958c025a2a1de40b8edb615b2d99a962c6c84019 (diff) | |
parent | 1ca5b7d95315c42cf0b78d33cd316e404a9f137c (diff) |
Merge tag 'at91-drivers' of git://github.com/at91linux/linux-at91 into next/drivers
From Nicolas Ferre:
AT91 crypto drivers DT support:
- add DT to sha/des/aes existing drivers
- add DMA DT
- all documentation added to crypto/atmel-crypto.txt file
* tag 'at91-drivers' of git://github.com/at91linux/linux-at91:
crypto: atmel-sha - add sha information to the log
crypto: atmel-sha - add support for Device Tree
crypto: atmel-tdes - add support for Device Tree
crypto: atmel-aes - add support for Device Tree
Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'drivers/crypto')
-rw-r--r-- | drivers/crypto/atmel-aes.c | 143 | ||||
-rw-r--r-- | drivers/crypto/atmel-sha.c | 103 | ||||
-rw-r--r-- | drivers/crypto/atmel-tdes.c | 143 |
3 files changed, 266 insertions, 123 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 | ||
800 | err_dma_out: | 792 | err_dma_out: |
801 | dma_release_channel(dd->dma_lch_in.chan); | 793 | dma_release_channel(dd->dma_lch_in.chan); |
802 | err_dma_in: | 794 | err_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) | ||
1258 | static const struct of_device_id atmel_aes_dt_ids[] = { | ||
1259 | { .compatible = "atmel,at91sam9g46-aes" }, | ||
1260 | { /* sentinel */ } | ||
1261 | }; | ||
1262 | MODULE_DEVICE_TABLE(of, atmel_aes_dt_ids); | ||
1263 | |||
1264 | static 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 | ||
1292 | static inline struct crypto_platform_data *atmel_aes_of_init(struct platform_device *pdev) | ||
1293 | { | ||
1294 | return ERR_PTR(-EINVAL); | ||
1295 | } | ||
1296 | #endif | ||
1297 | |||
1264 | static int atmel_aes_probe(struct platform_device *pdev) | 1298 | static 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 | ||
diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c index eaed8bf183bc..0618be06b9fb 100644 --- a/drivers/crypto/atmel-sha.c +++ b/drivers/crypto/atmel-sha.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> |
@@ -1263,32 +1264,29 @@ static int atmel_sha_dma_init(struct atmel_sha_dev *dd, | |||
1263 | int err = -ENOMEM; | 1264 | int err = -ENOMEM; |
1264 | dma_cap_mask_t mask_in; | 1265 | dma_cap_mask_t mask_in; |
1265 | 1266 | ||
1266 | if (pdata && pdata->dma_slave->rxdata.dma_dev) { | 1267 | /* Try to grab DMA channel */ |
1267 | /* Try to grab DMA channel */ | 1268 | dma_cap_zero(mask_in); |
1268 | dma_cap_zero(mask_in); | 1269 | dma_cap_set(DMA_SLAVE, mask_in); |
1269 | dma_cap_set(DMA_SLAVE, mask_in); | ||
1270 | 1270 | ||
1271 | dd->dma_lch_in.chan = dma_request_channel(mask_in, | 1271 | dd->dma_lch_in.chan = dma_request_slave_channel_compat(mask_in, |
1272 | atmel_sha_filter, &pdata->dma_slave->rxdata); | 1272 | atmel_sha_filter, &pdata->dma_slave->rxdata, dd->dev, "tx"); |
1273 | 1273 | if (!dd->dma_lch_in.chan) { | |
1274 | if (!dd->dma_lch_in.chan) | 1274 | dev_warn(dd->dev, "no DMA channel available\n"); |
1275 | return err; | 1275 | return err; |
1276 | |||
1277 | dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV; | ||
1278 | dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base + | ||
1279 | SHA_REG_DIN(0); | ||
1280 | dd->dma_lch_in.dma_conf.src_maxburst = 1; | ||
1281 | dd->dma_lch_in.dma_conf.src_addr_width = | ||
1282 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
1283 | dd->dma_lch_in.dma_conf.dst_maxburst = 1; | ||
1284 | dd->dma_lch_in.dma_conf.dst_addr_width = | ||
1285 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
1286 | dd->dma_lch_in.dma_conf.device_fc = false; | ||
1287 | |||
1288 | return 0; | ||
1289 | } | 1276 | } |
1290 | 1277 | ||
1291 | return -ENODEV; | 1278 | dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV; |
1279 | dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base + | ||
1280 | SHA_REG_DIN(0); | ||
1281 | dd->dma_lch_in.dma_conf.src_maxburst = 1; | ||
1282 | dd->dma_lch_in.dma_conf.src_addr_width = | ||
1283 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
1284 | dd->dma_lch_in.dma_conf.dst_maxburst = 1; | ||
1285 | dd->dma_lch_in.dma_conf.dst_addr_width = | ||
1286 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
1287 | dd->dma_lch_in.dma_conf.device_fc = false; | ||
1288 | |||
1289 | return 0; | ||
1292 | } | 1290 | } |
1293 | 1291 | ||
1294 | static void atmel_sha_dma_cleanup(struct atmel_sha_dev *dd) | 1292 | static void atmel_sha_dma_cleanup(struct atmel_sha_dev *dd) |
@@ -1326,6 +1324,48 @@ static void atmel_sha_get_cap(struct atmel_sha_dev *dd) | |||
1326 | } | 1324 | } |
1327 | } | 1325 | } |
1328 | 1326 | ||
1327 | #if defined(CONFIG_OF) | ||
1328 | static const struct of_device_id atmel_sha_dt_ids[] = { | ||
1329 | { .compatible = "atmel,at91sam9g46-sha" }, | ||
1330 | { /* sentinel */ } | ||
1331 | }; | ||
1332 | |||
1333 | MODULE_DEVICE_TABLE(of, atmel_sha_dt_ids); | ||
1334 | |||
1335 | static struct crypto_platform_data *atmel_sha_of_init(struct platform_device *pdev) | ||
1336 | { | ||
1337 | struct device_node *np = pdev->dev.of_node; | ||
1338 | struct crypto_platform_data *pdata; | ||
1339 | |||
1340 | if (!np) { | ||
1341 | dev_err(&pdev->dev, "device node not found\n"); | ||
1342 | return ERR_PTR(-EINVAL); | ||
1343 | } | ||
1344 | |||
1345 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
1346 | if (!pdata) { | ||
1347 | dev_err(&pdev->dev, "could not allocate memory for pdata\n"); | ||
1348 | return ERR_PTR(-ENOMEM); | ||
1349 | } | ||
1350 | |||
1351 | pdata->dma_slave = devm_kzalloc(&pdev->dev, | ||
1352 | sizeof(*(pdata->dma_slave)), | ||
1353 | GFP_KERNEL); | ||
1354 | if (!pdata->dma_slave) { | ||
1355 | dev_err(&pdev->dev, "could not allocate memory for dma_slave\n"); | ||
1356 | devm_kfree(&pdev->dev, pdata); | ||
1357 | return ERR_PTR(-ENOMEM); | ||
1358 | } | ||
1359 | |||
1360 | return pdata; | ||
1361 | } | ||
1362 | #else /* CONFIG_OF */ | ||
1363 | static inline struct crypto_platform_data *atmel_sha_of_init(struct platform_device *dev) | ||
1364 | { | ||
1365 | return ERR_PTR(-EINVAL); | ||
1366 | } | ||
1367 | #endif | ||
1368 | |||
1329 | static int atmel_sha_probe(struct platform_device *pdev) | 1369 | static int atmel_sha_probe(struct platform_device *pdev) |
1330 | { | 1370 | { |
1331 | struct atmel_sha_dev *sha_dd; | 1371 | struct atmel_sha_dev *sha_dd; |
@@ -1402,13 +1442,23 @@ static int atmel_sha_probe(struct platform_device *pdev) | |||
1402 | if (sha_dd->caps.has_dma) { | 1442 | if (sha_dd->caps.has_dma) { |
1403 | pdata = pdev->dev.platform_data; | 1443 | pdata = pdev->dev.platform_data; |
1404 | if (!pdata) { | 1444 | if (!pdata) { |
1405 | dev_err(&pdev->dev, "platform data not available\n"); | 1445 | pdata = atmel_sha_of_init(pdev); |
1446 | if (IS_ERR(pdata)) { | ||
1447 | dev_err(&pdev->dev, "platform data not available\n"); | ||
1448 | err = PTR_ERR(pdata); | ||
1449 | goto err_pdata; | ||
1450 | } | ||
1451 | } | ||
1452 | if (!pdata->dma_slave) { | ||
1406 | err = -ENXIO; | 1453 | err = -ENXIO; |
1407 | goto err_pdata; | 1454 | goto err_pdata; |
1408 | } | 1455 | } |
1409 | err = atmel_sha_dma_init(sha_dd, pdata); | 1456 | err = atmel_sha_dma_init(sha_dd, pdata); |
1410 | if (err) | 1457 | if (err) |
1411 | goto err_sha_dma; | 1458 | goto err_sha_dma; |
1459 | |||
1460 | dev_info(dev, "using %s for DMA transfers\n", | ||
1461 | dma_chan_name(sha_dd->dma_lch_in.chan)); | ||
1412 | } | 1462 | } |
1413 | 1463 | ||
1414 | spin_lock(&atmel_sha.lock); | 1464 | spin_lock(&atmel_sha.lock); |
@@ -1419,7 +1469,9 @@ static int atmel_sha_probe(struct platform_device *pdev) | |||
1419 | if (err) | 1469 | if (err) |
1420 | goto err_algs; | 1470 | goto err_algs; |
1421 | 1471 | ||
1422 | dev_info(dev, "Atmel SHA1/SHA256\n"); | 1472 | dev_info(dev, "Atmel SHA1/SHA256%s%s\n", |
1473 | sha_dd->caps.has_sha224 ? "/SHA224" : "", | ||
1474 | sha_dd->caps.has_sha_384_512 ? "/SHA384/SHA512" : ""); | ||
1423 | 1475 | ||
1424 | return 0; | 1476 | return 0; |
1425 | 1477 | ||
@@ -1483,6 +1535,7 @@ static struct platform_driver atmel_sha_driver = { | |||
1483 | .driver = { | 1535 | .driver = { |
1484 | .name = "atmel_sha", | 1536 | .name = "atmel_sha", |
1485 | .owner = THIS_MODULE, | 1537 | .owner = THIS_MODULE, |
1538 | .of_match_table = of_match_ptr(atmel_sha_dt_ids), | ||
1486 | }, | 1539 | }, |
1487 | }; | 1540 | }; |
1488 | 1541 | ||
diff --git a/drivers/crypto/atmel-tdes.c b/drivers/crypto/atmel-tdes.c index 4a99564a08e6..6cde5b530c69 100644 --- a/drivers/crypto/atmel-tdes.c +++ b/drivers/crypto/atmel-tdes.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> |
@@ -716,59 +717,50 @@ static int atmel_tdes_dma_init(struct atmel_tdes_dev *dd, | |||
716 | struct crypto_platform_data *pdata) | 717 | struct crypto_platform_data *pdata) |
717 | { | 718 | { |
718 | int err = -ENOMEM; | 719 | int err = -ENOMEM; |
719 | dma_cap_mask_t mask_in, mask_out; | 720 | dma_cap_mask_t mask; |
721 | |||
722 | dma_cap_zero(mask); | ||
723 | dma_cap_set(DMA_SLAVE, mask); | ||
724 | |||
725 | /* Try to grab 2 DMA channels */ | ||
726 | dd->dma_lch_in.chan = dma_request_slave_channel_compat(mask, | ||
727 | atmel_tdes_filter, &pdata->dma_slave->rxdata, dd->dev, "tx"); | ||
728 | if (!dd->dma_lch_in.chan) | ||
729 | goto err_dma_in; | ||
730 | |||
731 | dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV; | ||
732 | dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base + | ||
733 | TDES_IDATA1R; | ||
734 | dd->dma_lch_in.dma_conf.src_maxburst = 1; | ||
735 | dd->dma_lch_in.dma_conf.src_addr_width = | ||
736 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
737 | dd->dma_lch_in.dma_conf.dst_maxburst = 1; | ||
738 | dd->dma_lch_in.dma_conf.dst_addr_width = | ||
739 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
740 | dd->dma_lch_in.dma_conf.device_fc = false; | ||
741 | |||
742 | dd->dma_lch_out.chan = dma_request_slave_channel_compat(mask, | ||
743 | atmel_tdes_filter, &pdata->dma_slave->txdata, dd->dev, "rx"); | ||
744 | if (!dd->dma_lch_out.chan) | ||
745 | goto err_dma_out; | ||
746 | |||
747 | dd->dma_lch_out.dma_conf.direction = DMA_DEV_TO_MEM; | ||
748 | dd->dma_lch_out.dma_conf.src_addr = dd->phys_base + | ||
749 | TDES_ODATA1R; | ||
750 | dd->dma_lch_out.dma_conf.src_maxburst = 1; | ||
751 | dd->dma_lch_out.dma_conf.src_addr_width = | ||
752 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
753 | dd->dma_lch_out.dma_conf.dst_maxburst = 1; | ||
754 | dd->dma_lch_out.dma_conf.dst_addr_width = | ||
755 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
756 | dd->dma_lch_out.dma_conf.device_fc = false; | ||
720 | 757 | ||
721 | if (pdata && pdata->dma_slave->txdata.dma_dev && | 758 | return 0; |
722 | pdata->dma_slave->rxdata.dma_dev) { | ||
723 | |||
724 | /* Try to grab 2 DMA channels */ | ||
725 | dma_cap_zero(mask_in); | ||
726 | dma_cap_set(DMA_SLAVE, mask_in); | ||
727 | |||
728 | dd->dma_lch_in.chan = dma_request_channel(mask_in, | ||
729 | atmel_tdes_filter, &pdata->dma_slave->rxdata); | ||
730 | |||
731 | if (!dd->dma_lch_in.chan) | ||
732 | goto err_dma_in; | ||
733 | |||
734 | dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV; | ||
735 | dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base + | ||
736 | TDES_IDATA1R; | ||
737 | dd->dma_lch_in.dma_conf.src_maxburst = 1; | ||
738 | dd->dma_lch_in.dma_conf.src_addr_width = | ||
739 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
740 | dd->dma_lch_in.dma_conf.dst_maxburst = 1; | ||
741 | dd->dma_lch_in.dma_conf.dst_addr_width = | ||
742 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
743 | dd->dma_lch_in.dma_conf.device_fc = false; | ||
744 | |||
745 | dma_cap_zero(mask_out); | ||
746 | dma_cap_set(DMA_SLAVE, mask_out); | ||
747 | dd->dma_lch_out.chan = dma_request_channel(mask_out, | ||
748 | atmel_tdes_filter, &pdata->dma_slave->txdata); | ||
749 | |||
750 | if (!dd->dma_lch_out.chan) | ||
751 | goto err_dma_out; | ||
752 | |||
753 | dd->dma_lch_out.dma_conf.direction = DMA_DEV_TO_MEM; | ||
754 | dd->dma_lch_out.dma_conf.src_addr = dd->phys_base + | ||
755 | TDES_ODATA1R; | ||
756 | dd->dma_lch_out.dma_conf.src_maxburst = 1; | ||
757 | dd->dma_lch_out.dma_conf.src_addr_width = | ||
758 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
759 | dd->dma_lch_out.dma_conf.dst_maxburst = 1; | ||
760 | dd->dma_lch_out.dma_conf.dst_addr_width = | ||
761 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
762 | dd->dma_lch_out.dma_conf.device_fc = false; | ||
763 | |||
764 | return 0; | ||
765 | } else { | ||
766 | return -ENODEV; | ||
767 | } | ||
768 | 759 | ||
769 | err_dma_out: | 760 | err_dma_out: |
770 | dma_release_channel(dd->dma_lch_in.chan); | 761 | dma_release_channel(dd->dma_lch_in.chan); |
771 | err_dma_in: | 762 | err_dma_in: |
763 | dev_warn(dd->dev, "no DMA channel available\n"); | ||
772 | return err; | 764 | return err; |
773 | } | 765 | } |
774 | 766 | ||
@@ -1317,6 +1309,47 @@ static void atmel_tdes_get_cap(struct atmel_tdes_dev *dd) | |||
1317 | } | 1309 | } |
1318 | } | 1310 | } |
1319 | 1311 | ||
1312 | #if defined(CONFIG_OF) | ||
1313 | static const struct of_device_id atmel_tdes_dt_ids[] = { | ||
1314 | { .compatible = "atmel,at91sam9g46-tdes" }, | ||
1315 | { /* sentinel */ } | ||
1316 | }; | ||
1317 | MODULE_DEVICE_TABLE(of, atmel_tdes_dt_ids); | ||
1318 | |||
1319 | static struct crypto_platform_data *atmel_tdes_of_init(struct platform_device *pdev) | ||
1320 | { | ||
1321 | struct device_node *np = pdev->dev.of_node; | ||
1322 | struct crypto_platform_data *pdata; | ||
1323 | |||
1324 | if (!np) { | ||
1325 | dev_err(&pdev->dev, "device node not found\n"); | ||
1326 | return ERR_PTR(-EINVAL); | ||
1327 | } | ||
1328 | |||
1329 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
1330 | if (!pdata) { | ||
1331 | dev_err(&pdev->dev, "could not allocate memory for pdata\n"); | ||
1332 | return ERR_PTR(-ENOMEM); | ||
1333 | } | ||
1334 | |||
1335 | pdata->dma_slave = devm_kzalloc(&pdev->dev, | ||
1336 | sizeof(*(pdata->dma_slave)), | ||
1337 | GFP_KERNEL); | ||
1338 | if (!pdata->dma_slave) { | ||
1339 | dev_err(&pdev->dev, "could not allocate memory for dma_slave\n"); | ||
1340 | devm_kfree(&pdev->dev, pdata); | ||
1341 | return ERR_PTR(-ENOMEM); | ||
1342 | } | ||
1343 | |||
1344 | return pdata; | ||
1345 | } | ||
1346 | #else /* CONFIG_OF */ | ||
1347 | static inline struct crypto_platform_data *atmel_tdes_of_init(struct platform_device *pdev) | ||
1348 | { | ||
1349 | return ERR_PTR(-EINVAL); | ||
1350 | } | ||
1351 | #endif | ||
1352 | |||
1320 | static int atmel_tdes_probe(struct platform_device *pdev) | 1353 | static int atmel_tdes_probe(struct platform_device *pdev) |
1321 | { | 1354 | { |
1322 | struct atmel_tdes_dev *tdes_dd; | 1355 | struct atmel_tdes_dev *tdes_dd; |
@@ -1399,13 +1432,24 @@ static int atmel_tdes_probe(struct platform_device *pdev) | |||
1399 | if (tdes_dd->caps.has_dma) { | 1432 | if (tdes_dd->caps.has_dma) { |
1400 | pdata = pdev->dev.platform_data; | 1433 | pdata = pdev->dev.platform_data; |
1401 | if (!pdata) { | 1434 | if (!pdata) { |
1402 | dev_err(&pdev->dev, "platform data not available\n"); | 1435 | pdata = atmel_tdes_of_init(pdev); |
1436 | if (IS_ERR(pdata)) { | ||
1437 | dev_err(&pdev->dev, "platform data not available\n"); | ||
1438 | err = PTR_ERR(pdata); | ||
1439 | goto err_pdata; | ||
1440 | } | ||
1441 | } | ||
1442 | if (!pdata->dma_slave) { | ||
1403 | err = -ENXIO; | 1443 | err = -ENXIO; |
1404 | goto err_pdata; | 1444 | goto err_pdata; |
1405 | } | 1445 | } |
1406 | err = atmel_tdes_dma_init(tdes_dd, pdata); | 1446 | err = atmel_tdes_dma_init(tdes_dd, pdata); |
1407 | if (err) | 1447 | if (err) |
1408 | goto err_tdes_dma; | 1448 | goto err_tdes_dma; |
1449 | |||
1450 | dev_info(dev, "using %s, %s for DMA transfers\n", | ||
1451 | dma_chan_name(tdes_dd->dma_lch_in.chan), | ||
1452 | dma_chan_name(tdes_dd->dma_lch_out.chan)); | ||
1409 | } | 1453 | } |
1410 | 1454 | ||
1411 | spin_lock(&atmel_tdes.lock); | 1455 | spin_lock(&atmel_tdes.lock); |
@@ -1487,6 +1531,7 @@ static struct platform_driver atmel_tdes_driver = { | |||
1487 | .driver = { | 1531 | .driver = { |
1488 | .name = "atmel_tdes", | 1532 | .name = "atmel_tdes", |
1489 | .owner = THIS_MODULE, | 1533 | .owner = THIS_MODULE, |
1534 | .of_match_table = of_match_ptr(atmel_tdes_dt_ids), | ||
1490 | }, | 1535 | }, |
1491 | }; | 1536 | }; |
1492 | 1537 | ||