aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto
diff options
context:
space:
mode:
authorNicolas Ferre <nicolas.ferre@atmel.com>2013-10-15 09:36:34 -0400
committerNicolas Ferre <nicolas.ferre@atmel.com>2013-12-12 12:39:36 -0500
commitabfe7ae407c44de51f0fec8d87d448c7c27e1285 (patch)
tree73e9883b42144c0ee3ae4ac7c8704d2f447af02e /drivers/crypto
parent84c8976b643af63150072e6c3e5f156dd6f9c910 (diff)
crypto: atmel-sha - add support for Device Tree
Add support for Device Tree and use of the DMA DT API to get the channels if needed. 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-sha.c99
1 files changed, 75 insertions, 24 deletions
diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c
index eaed8bf183bc..ecfdf727cc36 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
1294static void atmel_sha_dma_cleanup(struct atmel_sha_dev *dd) 1292static 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)
1328static const struct of_device_id atmel_sha_dt_ids[] = {
1329 { .compatible = "atmel,at91sam9g46-sha" },
1330 { /* sentinel */ }
1331};
1332
1333MODULE_DEVICE_TABLE(of, atmel_sha_dt_ids);
1334
1335static 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 */
1363static inline struct crypto_platform_data *atmel_sha_of_init(struct platform_device *dev)
1364{
1365 return ERR_PTR(-EINVAL);
1366}
1367#endif
1368
1329static int atmel_sha_probe(struct platform_device *pdev) 1369static 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);
@@ -1483,6 +1533,7 @@ static struct platform_driver atmel_sha_driver = {
1483 .driver = { 1533 .driver = {
1484 .name = "atmel_sha", 1534 .name = "atmel_sha",
1485 .owner = THIS_MODULE, 1535 .owner = THIS_MODULE,
1536 .of_match_table = of_match_ptr(atmel_sha_dt_ids),
1486 }, 1537 },
1487}; 1538};
1488 1539